鄰接矩陣的深度優先遍歷


對《大話數據結構》P240——鄰接矩陣的深度優先遍歷,進行了自己的理解並完善了代碼。

鄰接表的深度優先遍歷見http://www.cnblogs.com/hslzju/p/5399832.html

舉個簡單的無序圖例子,為了節省時間傳手稿。

首先用鄰接矩陣的存儲結構創建該圖,再進行深度優先遍歷。

代碼和解釋如下(VS2012測試通過):

 1 #include <iostream>
 2 #include <stdlib.h>
 3 using namespace std;  4 
 5 typedef struct//圖的鄰接矩陣存儲結構
 6 {  7     char vexs[5];  8     int arc[5][5];  9     int numVertexes,numEdges; 10 }MGraph; 11 
12 MGraph *CreateMGraph(MGraph *G)//圖的創建
13 { 14     G=(MGraph*)malloc(sizeof(MGraph)); 15     int i,j,k; 16     cout<<"input numVertexes and numEdges"<<endl; 17     cin>>G->numVertexes>>G->numEdges;//輸入5 8
18     cout<<"input numVertexes"<<endl; 19     for(i=0;i<G->numVertexes;i++) 20         cin>>G->vexs[i];//每次循環依次輸入A B C D E
21     for(i=0;i<G->numVertexes;i++) 22         for(j=0;j<G->numVertexes;j++) 23             G->arc[i][j]=0; 24     for(k=0;k<G->numEdges;k++) 25  { 26         cout<<"input vi and vj"<<endl; 27         cin>>i>>j;//每次循環依次輸入0 1,0 2,0 3,0 4,1 2,1 4,2 3,3 4
28         G->arc[i][j]=1; 29         G->arc[j][i]=1; 30  } 31     return G; 32 } 33 
34 int visited[5];//設置為全局變量,DFS和DFSTraverse函數都有用到 35 
36 //以下標為i的頂點vexs[i]開始訪問,進行一次深度優先遞歸,對連通圖,可以訪問到所有的頂點
37 void DFS(MGraph *G,int i) 38 { 39     visited[i]=1;//訪問過的頂點標記為1
40     cout<<G->vexs[i]<<" ";//遞歸之前需要打印當前訪問的頂點
41     for(int j=0;j<G->numVertexes;j++)//從第0個頂點開始判斷,直到最后一個頂點
42         if((G->arc[i][j]==1)&&(!visited[j]))//若頂點vexs[j]與頂點vexs[i]相連,並且vexs[j]沒有訪問過 
43             DFS(G,j);//那就訪問vexs[j] 44     //cout<<G->vexs[i]<<" ";//如果寫在最后,則逆序輸出,可以將上面的cout注釋掉試一下
45 } 46 
47 //鄰接矩陣的深度遍歷
48 void DFSTraverse(MGraph *G) 49 { 50     for(int i=0;i<G->numVertexes;i++) 51         visited[i]=0;//初始化所有頂點都是未訪問過
52     for(int i=0;i<G->numVertexes;i++) 53         if(!visited[i]) DFS(G,i); 54     //從vexs[0]開始進行深度優先遞歸,若是連通圖,只會執行一次DFS(G,0) 55     //因為深度優先遞歸后每個visited[i]都是1,不會再執行if了 56     //若是非連通圖,可能會執行到DFS(G,1),DFS(G,2),DFS(G,3),DFS(G,4)
57 } 58 
59 int main() 60 { 61     MGraph *p=NULL; 62     p=CreateMGraph(p);//這里也可以用二級指針,參考二叉樹為什么用二級指針作為參數那篇博客
63     cout<<p->vexs[0]<<" "<<p->vexs[1]<<" "<<p->vexs[2]<<" "<<p->vexs[3]<<" "<<p->vexs[4]<<endl; 64     cout<<p->arc[0][1]<<" "<<p->arc[0][2]<<" "<<p->arc[0][3]<<" "<<p->arc[0][4]<<" "<<p->arc[1][2]<<" "<<p->arc[1][4]<<" "<<p->arc[2][3]<<" "<<p->arc[3][4]<<endl; 65     //驗證創建是否正確 66     //DFS(p,2);//舉個例子,若從下標2開始,執行一次DFS(G,2),輸出的遍歷順序是CABED
67     DFSTraverse(p);//輸出的遍歷順序是ABCDE
68 }

1、先理解void DFS(MGraph *G,int i)這個函數,假設從下標2開始,執行一次DFS(G,2),那么遍歷結果是CABED

main函數中用DFS(p,2);把DFSTraverse(p);注釋掉。

由於是連通圖,執行一次DFS(G,2)即可遍歷全部頂點。

2、考慮問題得全面,如果是非連通圖,執行一次DFS(G,2),會有頂點沒有被遍歷到。解決辦法是依次執行DFS(G,0),DFS(G,1),DFS(G,2),DFS(G,3),DFS(G,4)即可。用visited[i]對是否訪問過該頂點標記,防止不必要的循環。

main函數中用DFSTraverse(p);把DFS(p,2);注釋掉。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM