图:BFS(深度优先搜索)图解分析代码实现
文章目錄
- 一、介紹
- 二、圖的建立
- 2.1建立圖類(lèi)
- 2.2建立圖
- 三、BFS
- 3.1圖解:
- 3.2代碼
- 四、DFS和BFS完整代碼
一、介紹
圖的DFS(深度優(yōu)先搜索)與BFS(廣度優(yōu)先搜索)是圖的兩種遍歷方式。
主要區(qū)別在于當(dāng)?shù)竭_(dá)圖中的一個(gè)頂點(diǎn)后,DFS直接到達(dá)其中的一個(gè)(未遍歷過(guò)的)頂點(diǎn),之后再以這個(gè)新的頂點(diǎn)為基點(diǎn)重復(fù)上面的操作;而B(niǎo)FS到達(dá)圖中的一個(gè)頂點(diǎn)后,會(huì)先遍歷頂點(diǎn)周?chē)乃?#xff08;未遍歷過(guò)的)頂點(diǎn),然后在以其中的一個(gè)頂點(diǎn)為基點(diǎn),重復(fù)上面的操作。
舉個(gè)簡(jiǎn)單的例子:
如果分別用DFS和BFS進(jìn)行遍歷(以A為起點(diǎn)):
DFS:A B D E C (一條路走到頭)
BFS:A B C D E (先把A的周?chē)咄?#xff0c;接著走完B和C的周?chē)?
這篇文章將進(jìn)行BFS的分析,前一篇文章分析DFS:link
二、圖的建立
2.1建立圖類(lèi)
- 使用鄰接矩陣保存圖的信息。
- 為了給每個(gè)頂點(diǎn)起名字,使用了兩組map集合使頂點(diǎn)的名字與鄰接矩陣的數(shù)字一一對(duì)應(yīng)。
- 用boolean型數(shù)組記錄某節(jié)點(diǎn)是否被訪(fǎng)問(wèn)過(guò)。
代碼:
class graph{int vertexNum;//頂點(diǎn)數(shù)int edgeNum;//邊數(shù)int[][] adjacentMatrix;//鄰接矩陣boolean[] isVisited;//各頂點(diǎn)是否被訪(fǎng)問(wèn)Map<Character,Integer> nameToNum;Map<Integer,Character> numToName;int index;//頂點(diǎn)名稱(chēng)的下標(biāo)//構(gòu)造函數(shù)graph(int vertexnum, int edgenum){vertexNum = vertexnum;edgeNum = edgenum;adjacentMatrix = new int[vertexNum][vertexNum];nameToNum = new HashMap<>();numToName = new HashMap<>();isVisited = new boolean[vertexnum];}//頂點(diǎn)名稱(chēng)public void addVertexName(char vertex){nameToNum.put(vertex,index);index++;}//反轉(zhuǎn)頂點(diǎn)和其索引的對(duì)應(yīng)關(guān)系public void invertNameToNum(){Set<Character> chs = nameToNum.keySet();for (Character c : chs) {numToName.put(nameToNum.get(c),c);}}//打印兩個(gè)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建立圖
以下面的圖為例,建立圖結(jié)構(gòu)。
main方法中的代碼:
依次輸入相關(guān)信息:
出來(lái)的鄰接矩陣:
三、BFS
- BFS方法使用隊(duì)列進(jìn)行遍歷。
- 先將出發(fā)點(diǎn)壓入隊(duì)列,之后將其周?chē)狞c(diǎn)壓入隊(duì)列。
- 出隊(duì)列的過(guò)程就是遍歷輸出的過(guò)程。
- 每次出隊(duì)列時(shí),將其周?chē)?#xff08;未遍歷過(guò)的)頂點(diǎn)都入隊(duì)列。
- 當(dāng)隊(duì)列中沒(méi)有元素了,就表明遍歷完成。
3.1圖解:
以A為起始點(diǎn),將A的周?chē)旤c(diǎn)都入隊(duì)列(隊(duì)列=ABCD),A出隊(duì)列輸出A,A周?chē)捻旤c(diǎn)都入隊(duì)列了,不用執(zhí)行入隊(duì)列操作。
此時(shí)隊(duì)列=BCD,B出隊(duì)列,輸出B,將B相鄰頂點(diǎn)E入隊(duì)列。
此時(shí)隊(duì)列=BCDE,C出隊(duì)列,輸出C,將C相鄰頂點(diǎn)F入隊(duì)列。
此時(shí)隊(duì)列=DEF,D出隊(duì)列,輸出D,將D相鄰頂點(diǎn)G入隊(duì)列。
此時(shí)隊(duì)列=EFG,E出隊(duì)列,輸出E。后面循環(huán)這個(gè)操作,依次輸出E,F,G。
輸出順序?yàn)?#xff1a;A B C D E F G。
代碼:
3.2代碼
graph類(lèi)中的方法。
public void BFS(){Queue<Integer> qu = new ArrayDeque<>();//創(chuàng)建隊(duì)列qu.add(0);//從第0開(kāi)始訪(fǎng)問(wèn)System.out.print(numToName.get(0)+ "->");isVisited[0] = true;while(!qu.isEmpty()){//隊(duì)列是否為非空int po = qu.poll();//出隊(duì)列int start = 0;while(start < vertexNum ){//將周?chē)捻旤c(diǎn)(未標(biāo)記過(guò)的)入隊(duì)列if(adjacentMatrix[po][start] != 0 && !isVisited[start]){qu.add(start);//入隊(duì)列System.out.print(numToName.get(start)+"->");//輸出isVisited[start] = true;//標(biāo)記為訪(fǎng)問(wèn)過(guò)}start++;}}System.out.println("結(jié)束");}結(jié)果:A->B->C->D->E->F->G->結(jié)束
四、DFS和BFS完整代碼
package graph; import java.util.*;public class BFSAndDFS {public static void main(String[] args) {System.out.println("請(qǐng)輸入頂點(diǎn)數(shù):");Scanner sc = new Scanner(System.in);int vertexNum = sc.nextInt();System.out.println("請(qǐng)輸入邊數(shù):");int edgeNum = sc.nextInt();graph gr = new graph(vertexNum, edgeNum);for (int i = 0; i < vertexNum; i++) {System.out.println("請(qǐng)輸入第" + i + "個(gè)頂點(diǎn)的名稱(chēng):");gr.addVertexName(sc.next().charAt(0));//字符串的第一個(gè)字符存入}gr.invertNameToNum();for (int i = 0; i < edgeNum; i++) {System.out.println("請(qǐng)輸入第" + 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;//頂點(diǎn)數(shù)int edgeNum;//邊數(shù)int[][] adjacentMatrix;//鄰接矩陣boolean[] isVisited;//各頂點(diǎn)是否被訪(fǎng)問(wèn)Map<Character,Integer> nameToNum;Map<Integer,Character> numToName;int index;//頂點(diǎn)名稱(chēng)的下標(biāo)//構(gòu)造函數(shù)graph(int vertexnum, int edgenum){vertexNum = vertexnum;edgeNum = edgenum;adjacentMatrix = new int[vertexNum][vertexNum];nameToNum = new HashMap<>();numToName = new HashMap<>();isVisited = new boolean[vertexnum];}//頂點(diǎn)名稱(chēng)public void addVertexName(char vertex){nameToNum.put(vertex,index);index++;}//反轉(zhuǎn)頂點(diǎn)和其索引的對(duì)應(yīng)關(guān)系public void invertNameToNum(){Set<Character> chs = nameToNum.keySet();for (Character c : chs) {numToName.put(nameToNum.get(c),c);}}//打印兩個(gè)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();}}/*** 深度優(yōu)先遍歷* @param index 頂點(diǎn)的索引*/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("結(jié)束");for (int i = 0; i < isVisited.length; i++) {isVisited[i] = false;}}public void BFS(){Queue<Integer> qu = new ArrayDeque<>();//創(chuàng)建隊(duì)列qu.add(0);//從第0開(kāi)始訪(fǎng)問(wèn)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("結(jié)束");}}總結(jié)
以上是生活随笔為你收集整理的图:BFS(深度优先搜索)图解分析代码实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 图:DFS(深度优先搜索)图解分析代码实
- 下一篇: 01迷宫(BFS+记忆)