1. 程式人生 > >【資料結構】鄰接矩陣表示法的圖的深度廣度優先遍歷遞迴和非遞迴遍歷

【資料結構】鄰接矩陣表示法的圖的深度廣度優先遍歷遞迴和非遞迴遍歷

假設有以下結構的圖:

用鄰接矩陣表示如下:


因為他是無向圖,我們可以發現他的矩陣是對角對稱的。矩陣中每一行每一列都可以看成是一個頂點,矩陣中的元素表示著該頂點與其他頂點的關係,當元素的值為1說明它與對應列的頂點有邊相連,如果他們的值為0,表示他們沒有邊相連。下面我們來看看我們怎麼遍歷這個圖。

1.深度優先遍歷

假設我們從A這個頂點開始遍歷,當訪問到A點的時候它會找與A相連的第一個頂點B(為什麼B是第一個與A相連的頂點?請看矩陣),並且訪問B,訪問到B點,它會碰到到與B第一個相連的頂點A,但是A頂點已經訪問過,他就去找與B相連的下一個頂點D,並且訪問。訪問到D的時候,他就會去找與D相連但是沒有訪問過的頂點E,並訪問。訪問了E,他又去尋找與E相連並且未被訪問過的頂點F.訪問F後,並訪問F相連的節點,發現與F相連的節點都已被訪問過。結束遍歷。所以該無向圖的深度遍歷的順序為:

A->B->D->C->E->F

深度優先遍歷我們可以用棧來模擬,並且我們要用一個數組來儲存某個頂點是否被訪問過,深度優先遍歷的程式碼如下:

[java] view plain copy  print?在CODE上檢視程式碼片派生到我的程式碼片
  1. privatestaticint matrix[][]=  
  2. {  
  3.         {0,1,1,1,0,0},//A
  4.         {1,0,0,1,0,0},//B
  5.         {1,0,0,1,1,0},//C
  6.         {1,1,1,0,0,1},//D
  7.         {0,0,1,0,0,1},//E
  8.         {0,0,0,1,1,0}//F
  9. };  
  10. //每個頂點的資料表示,方便檢視
  11. privatestatic String str="ABCDEF";  
  12. blic staticvoid DFS(int line) {  
  13. Stack<Integer> stack=new Stack<Integer>();  
  14. boolean[] isVisit=newboolean[6];//儲存每個頂點是否訪問過
  15. Arrays.fill(isVisit, false);  
  16. stack.push(line);//第一個頂點入棧
  17. int temp;  
  18. int cur = 0;  
  19. boolean isFirst;  
  20. while(!stack.empty()){//如果棧不為空
  21.     temp=stack.pop();  
  22.     if(!isVisit[cur])  
  23.     System.out.print(str.charAt(temp)+" ");  
  24.     isFirst=true;//記錄元素在矩陣的行中是否為第一個節點
  25.     isVisit[temp]=true;  
  26.     for (int i = 0; i<isVisit.length; i++) {  
  27.         if (matrix[temp][i]==1&&!isVisit[i]) {//1說明有通路
  28.             if (isFirst) {  
  29.                 isFirst=false;  
  30.                 cur=i;  
  31.             }else{  
  32.                 stack.push(i);  
  33.             }  
  34.         }  
  35.      }  
  36.     //每行第一個未被訪問的頂點最後入棧
  37.     if(!isVisit[cur])  
  38.     stack.push(cur);  
  39. }  

2.廣度優先遍歷

廣度優先遍歷的思路是,先把與之相連的頂點都訪問一遍,再把該頂點的頂點訪問一遍,以此類推。在這裡就不詳細說明了。該圖的廣度優先遍歷的順序是:A->B->C->D->E->F

根據廣度優先遍歷的特點,我們用佇列來模擬,程式碼如下:

[java] view plain copy  print?在CODE上檢視程式碼片派生到我的程式碼片
  1. privatestaticint matrix[][]=  
  2.         {  
  3.                 {0,1,1,1,0,0},//A
  4.                 {1,0,0,1,0,0},//B
  5.                 {1,0,0,1,1,0},//C
  6.                 {1,1,1,0,0,1},//D
  7.                 {0,0,1,0,0,1},//E
  8.                 {0,0,0,1,1,0}//F
  9.         };  
  10.   //每個頂點的資料表示,方便檢視
  11.   privatestatic String str="ABCDEF";  
  12.     /** 
  13.      * 非遞迴廣度優先遍歷鄰接矩陣圖 
  14.      * @param line 遍歷的起點 
  15.      */
  16.     publicstaticvoid BFS(int line)  
  17.     {  
  18.         boolean[] isVisit=newboolean[6];//儲存每個頂點是否訪問過
  19.         Arrays.fill(isVisit, false);  
  20.         int temp;  
  21.         Queue<Integer> queue=new LinkedList<Integer>();  
  22.         queue.offer(line);//插入佇列
  23.         while (!queue.isEmpty()) {  
  24.             temp=queue.poll();  
  25.             if(!isVisit[temp])//如果沒有訪問過
  26.             System.out.print(str.charAt(temp)+" ");//列印結果
  27.             isVisit[temp]=true;//打完結果設為已訪問
  28.             for (int i = 0; i < isVisit.length; i++) {  
  29.                 if(matrix[temp][i]==1&&!isVisit[i])  
  30.                 {  
  31.                     queue.offer(i);  
  32.                 }  
  33.             }  
  34.         }  
  35.     }