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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

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

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

文章目錄

  • 一、簡(jiǎn)介
  • 二、圖的建立
    • 2.1建立圖類(lèi)
    • 2.2建立圖
  • 三、DFS
    • 3.1圖解
    • 3.2代碼

一、簡(jiǎn)介

圖的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)行DFS的分析,下一篇文章分析BFS:link

二、圖的建立

2.1建立圖類(lèi)

  • 使用鄰接矩陣保存圖的信息。
  • 為了給每個(gè)頂點(diǎn)起名字,使用了兩組map集合使頂點(diǎn)的名字與鄰接矩陣的數(shù)字一一對(duì)應(yīng)。
  • 用boolean型數(shù)組記錄某節(jié)點(diǎn)是否被訪問(wèn)過(guò)。

代碼

class graph{int vertexNum;//頂點(diǎn)數(shù)int edgeNum;//邊數(shù)int[][] adjacentMatrix;//鄰接矩陣boolean[] isVisited;//各頂點(diǎn)是否被訪問(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方法中的代碼:

public static void main(String[] args) {//while (true) {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);//無(wú)向圖權(quán)重為1,不用輸入}gr.printAdjacentMatrix();}

依次輸入相關(guān)信息:


出來(lái)的鄰接矩陣:

三、DFS

3.1圖解

假設(shè)從A開(kāi)始:

A的下一個(gè)頂點(diǎn)是從鄰接矩陣中選擇的,A對(duì)應(yīng)第0行,從前往后找,找到第一個(gè)(未遍歷過(guò)的)就直接輸出。

以B為基點(diǎn)找,也就是找鄰接矩陣第1行,找第一個(gè)(未遍歷過(guò)的)。

以D為基點(diǎn)找,也就是找鄰接矩陣第3行,找第一個(gè)(未遍歷過(guò)的)。
同上。直接寫(xiě)出答案。

最終結(jié)果:A B D C F G E

3.2代碼

這是graph類(lèi)中的方法。

/*** 深度優(yōu)先遍歷* @param index 頂點(diǎn)的索引*/public void DFS(int index){System.out.print(numToName.get(index) + "->");//輸出節(jié)點(diǎn)isVisited[index] = true;int start = 0;while( start < vertexNum && (adjacentMatrix[index][start] == 0||(adjacentMatrix[index][start] != 0 && isVisited[start]))){//找下一個(gè)頂點(diǎn)start++;}if(start > vertexNum - 1){//周?chē)鷽](méi)有頂點(diǎn)了,就結(jié)束return;}DFS(start);//以下一個(gè)頂點(diǎn)為基點(diǎn)進(jìn)行DFS}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;}}

注意:DFS的重載(對(duì)所有頂點(diǎn)進(jìn)行遍歷)是為了防止下面的情況:

若沒(méi)有重載,遍歷到達(dá)F時(shí),因?yàn)槠渲車(chē)捻旤c(diǎn)都被訪問(wèn)過(guò)了,遍歷就會(huì)結(jié)束。重載可以確保所有的頂點(diǎn)都會(huì)被訪問(wèn)。

運(yùn)行結(jié)果:A->B->D->C->F->G->E->結(jié)束

總結(jié)

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

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。