參考博客:圖的深度優先遍歷(遞歸、非遞歸;鄰接表,鄰接矩陣)
本代碼有個問題:就是結點是對應存儲下標的,要解決這個問題,可以增加一個定位函數(LocateVec),不修改也可以使代碼簡潔些
關於非連通圖的bug已修改,就是增加了dfsTraverse函數循環遍歷一遍結點:沒訪問過則再做一次dfs
樣例一連通,樣例二非連通
1.鄰接表遞歸
#include<stdio.h> #include<stdlib.h> #include<string.h> #define MAX 100 typedef struct EdgeNode// 邊表結點 { int adjves;//存儲頂點的下標 struct EdgeNode* next;//連接下一個鄰點 }EdgeNode; typedef struct VertexNode//頂點表結點 { int ves;//頂點的值 EdgeNode* firstedge;//相連的頂點的值 }VertexNode,AdjList[MAX]; //鄰接表 typedef struct { AdjList adjlist; int ves;//頂點 int edge;//邊 int book[MAX];//判斷是否有被訪問過 }MGraph; void createMGraph(MGraph *G) { int i; int start; int end; EdgeNode *e; printf("please input the ves and edge:\n"); scanf("%d%d",&(G->ves),&(G->edge)); //初始化 printf("please input the ves:\n");//此處設置頂點與存儲下標相同且從零開始 for(i = 0; i < G->ves; i++)//輸入頂點 { scanf("%d",&(G->adjlist[i].ves)); G->adjlist[i].firstedge = NULL; } //創建鄰接矩陣 printf("please input the edges:\n"); for(i = 0; i < G->edge; i++) { scanf("%d%d",&start,&end); e =(EdgeNode*)malloc(sizeof(EdgeNode));//分配空間 e->adjves = end; e->next = G->adjlist[start].firstedge; G->adjlist[start].firstedge = e;//類似於鏈表的前插 e =(EdgeNode*)malloc(sizeof(EdgeNode));//分配空間 e->adjves = start; e->next = G->adjlist[end].firstedge; G->adjlist[end].firstedge = e;//類似於鏈表的前插 } } void dfs(MGraph *G,int ves) { EdgeNode *p; G->book[ves] = 1;//被訪問過的結點置為1 printf("%d ",G->adjlist[ves].ves); p = G->adjlist[ves].firstedge;//取頂點 while(p) { if(G->book[p->adjves] == 0)//未被訪問過 { dfs(G,p->adjves); } p = p->next; } } void dfsTraverse(MGraph *G){ int i; memset(G->book,0,sizeof(G->book));//清空標志位 for(i = 0; i < G->ves; i++) if(!G->book[i]) dfs(G, i); } int main() { MGraph G; createMGraph(&G); dfsTraverse(&G); return 0; } /* 輸入樣例_1: 5 6 0 1 2 3 4 0 1 1 2 2 3 2 0 3 4 0 4 輸入樣例_2: 5 4 0 1 2 3 4 0 1 0 2 1 2 3 4 */
樣例一結果:
樣例二結果:
2.鄰接表非遞歸
#include<iostream> #include<stdlib.h> #include<stack> #include<stdio.h> #include<string.h> #define MAX 100 using namespace std; typedef struct EdgeNode// 邊表結點 { int adjves;//存儲頂點的下標 struct EdgeNode* next;//連接下一個鄰點 }EdgeNode; typedef struct VertexNode//頂點表結點 { int ves;//頂點的值 EdgeNode* firstedge;//相連的頂點的值 }VertexNode,AdjList[MAX]; //鄰接表 typedef struct { AdjList adjlist; int ves;//頂點 int edge;//邊 int book[MAX];//判斷是否有被訪問過 }MGraph; void createMGraph(MGraph *G) { int i; int start; int end; EdgeNode *e; printf("please input the ves and edge:\n");//此處設置頂點與存儲下標相同且從零開始 scanf("%d%d",&(G->ves),&(G->edge)); //初始化 printf("please input the ves:\n"); for(i = 0; i < G->ves; i++)//輸入頂點 { scanf("%d",&(G->adjlist[i].ves)); G->adjlist[i].firstedge = NULL; } //創建鄰接矩陣 printf("please input the edges:\n"); for(i = 0; i < G->edge; i++) { scanf("%d%d",&start,&end); e =(EdgeNode*)malloc(sizeof(EdgeNode));//分配空間 e->adjves = end; e->next = G->adjlist[start].firstedge; G->adjlist[start].firstedge = e;//類似於鏈表的前插 e =(EdgeNode*)malloc(sizeof(EdgeNode));//分配空間 e->adjves = start; e->next = G->adjlist[end].firstedge; G->adjlist[end].firstedge = e;//類似於鏈表的前插 } } void dfs(MGraph *G,int i) { stack <int>s; EdgeNode *p; G->book[i]=1; s.push(i); printf("%d ", G->adjlist[i].ves); p = G->adjlist[i].firstedge; while(!s.empty()) { p = G->adjlist[s.top()].firstedge; while(p) { if(G->book[p->adjves] == 0) { G->book[p->adjves]=1; printf("%d ",G->adjlist[p->adjves].ves); s.push(p->adjves); p = G->adjlist[p->adjves].firstedge; } else p=p->next; } if(p == NULL) { s.pop(); } } } void dfsTraverse(MGraph *G){ int i; memset(G->book,0,sizeof(G->book));//清空標志位 for(i = 0; i < G->ves; i++) if(!G->book[i]) dfs(G, i); } int main() { MGraph G; createMGraph(&G); dfsTraverse(&G); return 0; }
樣例和運行結果與遞歸的一致