日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

图:BFS(深度优先搜索)图解分析代码实现

發布時間:2025/3/20 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图:BFS(深度优先搜索)图解分析代码实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 一、介紹
  • 二、圖的建立
    • 2.1建立圖類
    • 2.2建立圖
  • 三、BFS
    • 3.1圖解:
    • 3.2代碼
  • 四、DFS和BFS完整代碼

一、介紹

圖的DFS(深度優先搜索)與BFS(廣度優先搜索)是圖的兩種遍歷方式。

主要區別在于當到達圖中的一個頂點后,DFS直接到達其中的一個(未遍歷過的)頂點,之后再以這個新的頂點為基點重復上面的操作;而BFS到達圖中的一個頂點后,會先遍歷頂點周圍的所有(未遍歷過的)頂點,然后在以其中的一個頂點為基點,重復上面的操作。

舉個簡單的例子:

如果分別用DFS和BFS進行遍歷(以A為起點):
DFS:A B D E C (一條路走到頭)
BFS:A B C D E (先把A的周圍走完,接著走完B和C的周圍)

這篇文章將進行BFS的分析,前一篇文章分析DFS: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方法中的代碼:

public static void main(String[] args) {//while (true) {System.out.println("請輸入頂點數:");Scanner sc = new Scanner(System.in);int vertexNum = sc.nextInt();System.out.println("請輸入邊數:");int edgeNum = sc.nextInt();graph gr = new graph(vertexNum, edgeNum);for (int i = 0; i < vertexNum; i++) {System.out.println("請輸入第" + i + "個頂點的名稱:");gr.addVertexName(sc.next().charAt(0));//字符串的第一個字符存入}gr.invertNameToNum();for (int i = 0; i < edgeNum; i++) {System.out.println("請輸入第" + i + "條邊(name1 name2 weight):");gr.addEdge(sc.next().charAt(0), sc.next().charAt(0), 1);//無向圖權重為1,不用輸入}gr.printAdjacentMatrix();}

依次輸入相關信息:


出來的鄰接矩陣:

三、BFS

  • BFS方法使用隊列進行遍歷。
  • 先將出發點壓入隊列,之后將其周圍的點壓入隊列。
  • 出隊列的過程就是遍歷輸出的過程。
  • 每次出隊列時,將其周圍的(未遍歷過的)頂點都入隊列。
  • 當隊列中沒有元素了,就表明遍歷完成。

3.1圖解:

以A為起始點,將A的周圍頂點都入隊列(隊列=ABCD),A出隊列輸出A,A周圍的頂點都入隊列了,不用執行入隊列操作。

此時隊列=BCD,B出隊列,輸出B,將B相鄰頂點E入隊列。

此時隊列=BCDE,C出隊列,輸出C,將C相鄰頂點F入隊列。

此時隊列=DEF,D出隊列,輸出D,將D相鄰頂點G入隊列。

此時隊列=EFG,E出隊列,輸出E。后面循環這個操作,依次輸出E,F,G。

輸出順序為:A B C D E F G。
代碼:

3.2代碼

graph類中的方法。

public void BFS(){Queue<Integer> qu = new ArrayDeque<>();//創建隊列qu.add(0);//從第0開始訪問System.out.print(numToName.get(0)+ "->");isVisited[0] = true;while(!qu.isEmpty()){//隊列是否為非空int po = qu.poll();//出隊列int start = 0;while(start < vertexNum ){//將周圍的頂點(未標記過的)入隊列if(adjacentMatrix[po][start] != 0 && !isVisited[start]){qu.add(start);//入隊列System.out.print(numToName.get(start)+"->");//輸出isVisited[start] = true;//標記為訪問過}start++;}}System.out.println("結束");}

結果:A->B->C->D->E->F->G->結束

四、DFS和BFS完整代碼

package graph; import java.util.*;public class BFSAndDFS {public static void main(String[] args) {System.out.println("請輸入頂點數:");Scanner sc = new Scanner(System.in);int vertexNum = sc.nextInt();System.out.println("請輸入邊數:");int edgeNum = sc.nextInt();graph gr = new graph(vertexNum, edgeNum);for (int i = 0; i < vertexNum; i++) {System.out.println("請輸入第" + i + "個頂點的名稱:");gr.addVertexName(sc.next().charAt(0));//字符串的第一個字符存入}gr.invertNameToNum();for (int i = 0; i < edgeNum; i++) {System.out.println("請輸入第" + i + "條邊(name1 name2 weight):");gr.addEdge(sc.next().charAt(0), sc.next().charAt(0), 1);}gr.printAdjacentMatrix();gr.DFS();gr.BFS();}}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();}}/*** 深度優先遍歷* @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);}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;}}public void BFS(){Queue<Integer> qu = new ArrayDeque<>();//創建隊列qu.add(0);//從第0開始訪問System.out.print(numToName.get(0)+ "->");isVisited[0] = true;while(!qu.isEmpty()){int po = qu.poll();int start = 0;while(start < vertexNum ){if(adjacentMatrix[po][start] != 0 && !isVisited[start]){qu.add(start);System.out.print(numToName.get(start)+"->");isVisited[start] = true;}start++;}}System.out.println("結束");}}

總結

以上是生活随笔為你收集整理的图:BFS(深度优先搜索)图解分析代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。