數據結構系列是我學習做的筆記,會持續更新,源碼分享在github:數據結構,當然你也可以從下面的代碼片中獲取
注:github代碼更新會有延遲,關注不迷路😄
本篇博文簡單介紹鄰接表與其存儲圖的特點,並用java實現
1. 鄰接表
鄰接表(Adjacency list)是圖的一種鏈式存儲方法,其是由一個順序存儲的頂點表和n個鏈式存儲的邊表組成。其中,頂點表由定點節點組成,邊表是由邊(弧)節點組成的一個單鏈表,表示所有依附於頂點v_i的邊。
2. 具體實現代碼
2.1 圖的類型枚舉:GraphKind.java
package code.Graph;
/*
* 羅列圖的四種類型
* */
public enum GraphKind {
UDG, //無向圖----(UnDirected Graph)
DG, //有向圖----(Directed Graph)
UDN, //無向網----(UnDirected Network)
DN; //有向網----(Directed Network)
}
2.2 圖的接口:IGraph .java
package code.Graph;
/*
* 圖的存儲結構除了存儲圖中各個頂點的信息外,還要存儲與頂點相關聯的邊的信息,
* 圖的常見存儲結構有鄰接矩陣,鄰接表,鄰接多重表,十字鏈表
*
* 圖的接口
*
* */
public interface IGraph {
/**創建一個圖*/
public void createGraph();
/**返回圖中的頂點數*/
public int getVexNum();
/**返回圖中的邊數*/
public int getArcNum();
/**
* 給定點的位置v,返回其對應的頂點值,其中, 0 <= v < vexNum
* @param v
* */
public Object getVex(int v) throws Exception;
/**
* 給定頂點的值vex,返回其在圖中的位置,如果圖中不包含此定點,返回-1
* @param vex
*/
public int locateVex(Object vex);
/**
* 返回v的第一個鄰接點,若V沒有鄰接點,則返回-1,其中, 0 <= v < vexNum
* @param v
*/
public int firstAdjVex(int v) throws Exception;
/**
* 返回v相對於w的下一個鄰接點,若w是v的最後一個鄰接點,則返回-1,其中, 0 <= v, w < vexNum
* @param v
* @param w
*/
public int nextAdjVex(int v,int w) throws Exception;
}
2.3 頂點節點類:VNode.java
package code.Graph;
/**
* 圖的鄰接表存儲表示中的頂點節點類
* */
public class VNode {
public Object data;//頂點信息
public ArcNode firstArc;//指向第一條依附於該頂點的弧
public VNode(Object data) {
this(data,null);
}
public VNode(Object data, ArcNode firstArc) {
this.data = data;
this.firstArc = firstArc;
}
public VNode() {
this(null,null);
}
public Object getData() {
return data;
}
public ArcNode getFirstArc() {
return firstArc;
}
}
2.4 邊(或弧)節點類:ArcNode.java
package code.Graph;
/**
* 圖的鄰接表存儲表示中的邊(或弧)節點類
*
* */
public class ArcNode {
public int adjVex;//該弧所指向的頂點位置
public int value;//邊或弧的權值
private ArcNode nextArc;//指向下一條弧
public ArcNode(int adjVex, int value, ArcNode nextArc) {
this.adjVex = adjVex;
this.value = value;
this.nextArc = nextArc;
}
public ArcNode(int adjVex, int value) {
this(adjVex,value,null);
}
public ArcNode(int adjVex) {
this(adjVex,0,null);
}
public ArcNode() {
this(-1,0,null);
}
public int getAdjVex() {
return adjVex;
}
public int getValue() {
return value;
}
public ArcNode getNextArc() {
return nextArc;
}
public void setAdjVex(int adjVex) {
this.adjVex = adjVex;
}
public void setValue(int value) {
this.value = value;
}
public void setNextArc(ArcNode nextArc) {
this.nextArc = nextArc;
}
}
2.5 圖的鄰接表類:ALGraph.java
package code.Graph;
import java.util.Scanner;
public class ALGraph implements IGraph{
private GraphKind kind;//圖的種類標誌
private int vexNum,arcNum;//圖的當前頂點數和邊數
private VNode[] vexs;//頂點
public ALGraph() {
this(null,0,0,null);
}
public ALGraph(GraphKind kind, int vexNum, int arcNum, VNode[] vexs) {
this.kind = kind;
this.vexNum = vexNum;
this.arcNum = arcNum;
this.vexs = vexs;
}
/**
* 創建一個圖
*/
@Override
public void createGraph() {
Scanner sc = new Scanner(System.in);
System.out.println("請輸入圖的類型:");
GraphKind kind = GraphKind.valueOf(sc.next());
switch (kind){
case UDG:
createUDG();
return;
case DG:
createDG();
return;
case UDN:
createUDN();
return;
case DN:
createDN();
return;
}
}
//創建 圖,網 的工具方法
private void createNetworkOrGraphUnit(){
Scanner sc = new Scanner(System.in);
System.out.println("請分別輸入圖的頂點數,圖的邊數");
vexNum = sc.nextInt();//圖的頂點數
arcNum = sc.nextInt();//圖的邊數
vexs = new VNode[vexNum];//存儲頂點的數組
System.out.println("請分別輸入圖的各個頂點:");
for (int v = 0;v < vexNum;v++){//構造頂點向量
vexs[v] = new VNode(sc.next());
}
}
//有向圖
private void createDG() {
Scanner sc = new Scanner(System.in);
createNetworkOrGraphUnit();
System.out.println("請輸入各邊的頂點及其權值:");
for (int k = 0;k < arcNum;k++){
int v = locateVex(sc.next());//弧頭
int u = locateVex(sc.next());//弧尾
addArc(v,u,1);
}
}
//無向圖
private void createUDG() {
Scanner sc = new Scanner(System.in);
createNetworkOrGraphUnit();
System.out.println("請輸入各邊的頂點:");
for (int k = 0;k < arcNum;k++){
int v = locateVex(sc.next());//弧頭
int u = locateVex(sc.next());//弧尾
int value = 1;
addArc(v,u,value);
addArc(u,v,value);
}
}
//無向網
private void createUDN(){
Scanner sc = new Scanner(System.in);
createNetworkOrGraphUnit();
System.out.println("請輸入各邊的頂點及其權值:");
for (int k = 0;k < arcNum;k++){
int v = locateVex(sc.next());//弧頭
int u = locateVex(sc.next());//弧尾
int value = sc.nextInt();
addArc(v,u,value);
addArc(u,v,value);
}
}
//有向網
private void createDN(){
Scanner sc = new Scanner(System.in);
createNetworkOrGraphUnit();
System.out.println("請輸入各邊的頂點及其權值:");
for (int k = 0;k < arcNum;k++){
int v = locateVex(sc.next());//弧頭
int u = locateVex(sc.next());//弧尾
int value = sc.nextInt();
addArc(v,u,value);
}
}
/**
* 在位置爲v,u的頂點之間添加一條弧,其權值爲value
* */
public void addArc(int v,int u,int value){
ArcNode arc = new ArcNode(u,value);
arc.setNextArc(vexs[v].firstArc);
vexs[v].firstArc = arc;
}
/**
* 返回圖中的頂點數
*/
@Override
public int getVexNum() {
return vexNum;
}
/**
* 返回圖中的邊數
*/
@Override
public int getArcNum() {
return arcNum;
}
/**
* 給定點的位置v,返回其對應的頂點值,其中, 0 <= v < vexNum
*
* @param v
*/
@Override
public Object getVex(int v) throws Exception {
if (v < 0 && v >= vexNum){
throw new Exception("第" + v + "個頂點不存在!");
}
return vexs[v].getData();
}
/**
* 給定頂點的值vex,返回其在圖中的位置,如果圖中不包含此定點,返回-1
*
* @param vex
*/
@Override
public int locateVex(Object vex) {
for (int v = 0;v<vexNum;v++){
if (vexs[v].data.equals(vex)){
return v;
}
}
return -1;
}
/**
* 返回v的第一個鄰接點,若V沒有鄰接點,則返回-1,其中, 0 <= v < vexNum
*
* @param v
*/
@Override
public int firstAdjVex(int v) throws Exception {
if (v < 0 && v >= vexNum){
throw new Exception("第" + v + "個頂點不存在!");
}
VNode vex = vexs[v];
if (vex.firstArc != null){
return vex.firstArc.adjVex;
}else {
return -1;
}
}
/**
* 返回v相對於w的下一個鄰接點,若w是v的最後一個鄰接點,則返回-1,其中, 0 <= v, w < vexNum
*
* @param v
* @param w
*/
@Override
public int nextAdjVex(int v, int w) throws Exception {
if (v < 0 && v >= vexNum){
throw new Exception("第" + v + "個頂點不存在!");
}
VNode vex = vexs[v];
ArcNode arcvw = null;
for (ArcNode arc = vex.firstArc;arc != null;arc = arc.getNextArc()){
if (arc.adjVex == w){
arcvw = arc;
break;
}
}
if (arcvw != null && arcvw.getNextArc() != null){
return arcvw.getNextArc().adjVex;
}else {
return -1;
}
}
public GraphKind getKind() {
return kind;
}
public VNode[] getVexs() {
return vexs;
}
}
有關圖的鄰接矩陣實現見此鏈接