圖的鄰接表和DFS遍歷
阿新 • • 發佈:2019-02-02
鄰接矩陣和鄰接表的對比
之前一篇文章我們學習了 圖的鄰接矩陣和DFS遍歷, 鄰接矩陣對於圖來說是一種很不錯的儲存結構,但是也有特殊的情況,例如邊數很少的時候。
此時的鄰接矩陣,只有(v0,v1)和(v1, v0)有值,其他都是0或無窮。然而,所以對於鄰接矩陣來說,其它的空間都被浪費掉了,圖中結點數很少的時候,影響不大,但是對於結點數多,且邊數少的時候,效能影響就明顯了。所以我們可以考慮另外一種方式,使用連結串列的方式來儲存圖結構,也就是 鄰接表
鄰接表
鄰接表採用陣列和連結串列結合的方式儲存,具體的定義和處理看下圖例子:
1. 無向圖的鄰接表定義
2. 有向圖的鄰接表定義
程式碼實現無向圖鄰接表的建立和DFS遍歷
#include<stdio.h>
#include<stdlib.h>
#define MAXVEX 100
int visited[MAXVEX];
//邊表結點
typedef struct EdgeNode{
int adjvex; //結點下標
int weight; //結點權值
struct EdgeNode *next; //next指標
} EdgeNode;
//頂點表結點
typedef struct VertexNode{
int data; //頂點域
EdgeNode *firstedge; // 邊表指標
} VertexNode, AdjList[100];
//圖的鄰接表結構
typedef struct {
AdjList adjList;
int maxVertexes, numEdge; //頂點數和邊數
} Graph;
void createALGraph(Graph *G){
int i, j;
EdgeNode *e;
printf("輸入頂點數和邊數:");
scanf("%d%d", &G->maxVertexes, &G->numEdge);
//輸入頂點
for(i = 0; i < G->maxVertexes; i++){
scanf("%d", &G->adjList[i].data);
G->adjList[i].firstedge = NULL;
}
//輸入邊
printf("輸入邊(i, j)上的頂點:\n");
for(int k = 0; k < G->numEdge; k++){
scanf("%d%d", &i, &j);
e = (EdgeNode *) malloc (sizeof (EdgeNode));
e->adjvex = j;
e->next = G->adjList[i].firstedge;
G->adjList[i].firstedge = e;
e = (EdgeNode *) malloc (sizeof (EdgeNode));
e->adjvex = i;
e->next = G->adjList[j].firstedge;
G->adjList[j].firstedge = e;
}
}
void DFS(Graph *G, int i){
EdgeNode *p;
visited[i] = 1;
printf("%d", G->adjList[i].data);
p = G->adjList[i].firstedge;
while(p){
if(!visited[p->adjvex]){
DFS(G, p->adjvex);
}
p = p->next;
}
}
void DFSTraverse(Graph *G){
int i;
for(i = 0; i < G->maxVertexes; i++){
visited[i] = 0;
}
for(i = 0; i < G->maxVertexes; i++){
if(!visited[i]){
DFS(G, i);
}
}
}
int main(){
Graph G;
createALGraph(&G);
DFSTraverse(&G);
}
結果如下: