數據結構——圖的深度優先遍歷(鄰接矩陣表示+java版本)


1.深度優先遍歷(DFS)

圖的深度優先遍歷本質上是一棵樹的前序遍歷(即先遍歷自身,然后遍歷其左子樹,再遍歷右子樹),總之圖的深度優先遍歷是一個遞歸的過程。

如下圖所示,左圖是一個圖,右圖是圖的深度優先遍歷過程。我們假設從頂點A開始遍歷,A被標記后,A面前有兩個頂點B和F可以選擇,我們該選擇哪個呢?這里我們可以假設每次都選擇最右邊的頂點,因此我們選擇B頂點,B被標記后,緊接着有C、I、G三個頂點可選擇(如右圖的B節點下有三個子節點C、I、G),還按照最右邊原則,我們選擇C頂點進行遍歷。

以此類推遍歷到H頂點時(參考右圖),我們發現到F頂點時,其最右邊的A頂點已經被標記過,因此選擇第二右的G頂點。到頂點H時,我們發現H后面的D和E頂點都已經被我們標記過,現在已經無路可走,但此時並沒有結束,因為還有個I頂點還沒有被遍歷,這時候我們就要回溯,就好像樹的前序遍歷一樣,左子樹遍歷完會回溯到root節點,接着遍歷其右子樹。我們從H頂點回溯到G頂點,檢查G的三個頂點B、D、H是否有沒有被遍歷的,發現都已經被遍歷,那么我們繼續往上回溯,發現回溯到D頂點時,與其相連的四個頂點中,I頂點沒有被遍歷,接着就遍歷I頂點,遍歷完后繼續回溯,知道回溯到最初的A頂點,算法結束。

 代碼部分:

我們用一個類MGrapg01表示鄰接矩陣,其中包括鄰接矩陣的創建方法(此處省略,鄰接矩陣的創建可參考上一篇文章)。

其中DFS算法由DFS_map和DFS兩個方法構成,其中DFS_Map用來從起始點開始深度優先遍歷,DFS()方法完成深度優先遞歸操作。並且用一個visit數組來表示頂點被遍歷的狀態,若頂點被遍歷,則被標記為true,否則為false。

代碼是無向圖的深度遍歷,對於有向圖而言,它只是通道存在可行與不可行,算法上是沒有變化的,這里完全可以通用。

 1 public class MGraph01 {  2     public int numNodes;      //圖的頂點數目
 3     public int numEdges;      //圖的邊數
 4     public Object[] vexs;     //一維頂點數組
 5     public int[][] arcs;      //二維邊數組
 6     public static final int INF = Integer.MAX_VALUE; //無窮大
 7 
 8 
 9     /**
10  *此處省略鄰接矩陣的創建代碼,可參考第一篇文章 11  / 12 
13  /** 14  * 深度優先遍歷操作 15      */
16     public void DFS_Map() { 17         //初始化數組,每個值為false,默認為未訪問狀態
18         boolean[] visit = new boolean[numNodes]; 19         for (int i = 0; i < visit.length; i++) { 20             if (!visit[i]) { 21  DFS(i, visit); 22  } 23  } 24  } 25 
26     /**
27  * 無向圖的深度優先遞歸算法 28  * 29  * @param i 30      */
31     private void DFS(int i, boolean[] visit) { 32         visit[i] = true; 33         System.out.println("頂點" + vexs[i] + "已被遍歷"); 34         for (int j = 0; j < numNodes; j++) { 35             //對未被訪問的頂點遞歸調用
36             if (!visit[j] && arcs[i][j] == 1) { 37  DFS(j, visit); 38  } 39  } 40  } 41 }

代碼測試: 

 1 public class MGraph01Test {  2     public static void main(String[] args) {  3         //初始化一個鄰接矩陣對象
 4         MGraph01 graph01 = new MGraph01();  5         //調用createUDG方法來創建無向圖的鄰接矩陣
 6  graph01.createUDG();  7         //調用深度優先遍歷方法
 8  graph01.DFS_Map();  9  } 10 }

 


免責聲明!

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



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