图:DFS(深度优先搜索)图解分析代码实现
文章目錄
- 一、簡介
- 二、圖的建立
- 2.1建立圖類
- 2.2建立圖
- 三、DFS
- 3.1圖解
- 3.2代碼
一、簡介
圖的DFS(深度優先搜索)與BFS(廣度優先搜索)是圖的兩種遍歷方式。
主要區別在于當到達圖中的一個頂點后,DFS直接到達其中的一個(未遍歷過的)頂點,之后再以這個新的頂點為基點重復上面的操作;而BFS到達圖中的一個頂點后,會先遍歷頂點周圍的所有(未遍歷過的)頂點,然后在以其中的一個頂點為基點,重復上面的操作。
舉個簡單的例子:
如果分別用DFS和BFS進行遍歷(以A為起點):
DFS:A B D E C (一條路走到頭)
BFS:A B C D E (先把A的周圍走完,接著走完B和C的周圍)
這篇文章將進行DFS的分析,下一篇文章分析BFS:link
二、圖的建立
2.1建立圖類
- 使用鄰接矩陣保存圖的信息。
- 為了給每個頂點起名字,使用了兩組map集合使頂點的名字與鄰接矩陣的數字一一對應。
- 用boolean型數組記錄某節點是否被訪問過。
代碼:
class graph{int vertexNum;//頂點數int edgeNum;//邊數int[][] adjacentMatrix;//鄰接矩陣boolean[] isVisited;//各頂點是否被訪問Map<Character,Integer> nameToNum;Map<Integer,Character> numToName;int index;//頂點名稱的下標//構造函數graph(int vertexnum, int edgenum){vertexNum = vertexnum;edgeNum = edgenum;adjacentMatrix = new int[vertexNum][vertexNum];nameToNum = new HashMap<>();numToName = new HashMap<>();isVisited = new boolean[vertexnum];}//頂點名稱public void addVertexName(char vertex){nameToNum.put(vertex,index);index++;}//反轉頂點和其索引的對應關系public void invertNameToNum(){Set<Character> chs = nameToNum.keySet();for (Character c : chs) {numToName.put(nameToNum.get(c),c);}}//打印兩個mappublic void printMap(){System.out.println("name to num:");Set<Character> chs = nameToNum.keySet();for (Character c : chs) {System.out.println(c + "->" + nameToNum.get(c));}System.out.println();System.out.println("num to name:");Set<Integer> ins = numToName.keySet();for (Integer in : ins) {System.out.println(in+"->"+ numToName.get(in));}}//添加邊public void addEdge(char vertex1, char vertex2, int weight){adjacentMatrix[nameToNum.get(vertex1)][nameToNum.get(vertex2)] = weight;adjacentMatrix[nameToNum.get(vertex2)][nameToNum.get(vertex1)] = weight;}//打印鄰接矩陣public void printAdjacentMatrix(){for (int[] am : adjacentMatrix) {for (int i : am) {System.out.print(i + " ");}System.out.println();}}}2.2建立圖
以下面的圖為例,建立圖結構。
main方法中的代碼:
依次輸入相關信息:
出來的鄰接矩陣:
三、DFS
3.1圖解
假設從A開始:
A的下一個頂點是從鄰接矩陣中選擇的,A對應第0行,從前往后找,找到第一個(未遍歷過的)就直接輸出。
以B為基點找,也就是找鄰接矩陣第1行,找第一個(未遍歷過的)。
以D為基點找,也就是找鄰接矩陣第3行,找第一個(未遍歷過的)。
同上。直接寫出答案。
最終結果:A B D C F G E
3.2代碼
這是graph類中的方法。
/*** 深度優先遍歷* @param index 頂點的索引*/public void DFS(int index){System.out.print(numToName.get(index) + "->");//輸出節點isVisited[index] = true;int start = 0;while( start < vertexNum && (adjacentMatrix[index][start] == 0||(adjacentMatrix[index][start] != 0 && isVisited[start]))){//找下一個頂點start++;}if(start > vertexNum - 1){//周圍沒有頂點了,就結束return;}DFS(start);//以下一個頂點為基點進行DFS}public void DFS(){for (int i = 0; i < vertexNum; i++) {if(!isVisited[i]){DFS(i);}}System.out.println("結束");for (int i = 0; i < isVisited.length; i++) {isVisited[i] = false;}}注意:DFS的重載(對所有頂點進行遍歷)是為了防止下面的情況:
若沒有重載,遍歷到達F時,因為其周圍的頂點都被訪問過了,遍歷就會結束。重載可以確保所有的頂點都會被訪問。
運行結果:A->B->D->C->F->G->E->結束
總結
以上是生活随笔為你收集整理的图:DFS(深度优先搜索)图解分析代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 二叉树的前序、中序和后序遍历介绍及案例
- 下一篇: 图:BFS(深度优先搜索)图解分析代码实