1. 程式人生 > >圖的鄰接表和DFS遍歷

圖的鄰接表和DFS遍歷

鄰接矩陣和鄰接表的對比

之前一篇文章我們學習了 圖的鄰接矩陣和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); }

結果如下:

這裡寫圖片描述