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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

数据结构-深度优先遍历和广度优先遍历(漫画)

發布時間:2025/3/21 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构-深度优先遍历和广度优先遍历(漫画) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

?

—————? 第二天? —————

?

?

?

————————————

?

?

?

?

什么是 深度/廣度 優先遍歷?

深度優先遍歷簡稱DFS(Depth First Search),廣度優先遍歷簡稱BFS(Breadth First Search),它們是遍歷圖當中所有頂點的兩種方式。

這兩種遍歷方式有什么不同呢?我們來舉個栗子:

我們來到一個游樂場,游樂場里有11個景點。我們從景點0開始,要玩遍游樂場的所有景點,可以有什么樣的游玩次序呢?

?

第一種是一頭扎到底的玩法。我們選擇一條支路,盡可能不斷地深入,如果遇到死路就往回退,回退過程中如果遇到沒探索過的支路,就進入該支路繼續深入。

在圖中,我們首先選擇景點1的這條路,繼續深入到景點7、景點8,終于發現走不動了(景點旁邊的數字代表探索次序):

于是,我們退回到景點7,然后探索景點10,又走到了死胡同。于是,退回到景點1,探索景點9:

按照這個思路,我們再退回到景點0,后續依次探索景點2、3、5、4、6,終于玩遍了整個游樂場:

像這樣先深入探索,走到頭再回退尋找其他出路的遍歷方式,就叫做深度優先遍歷(DFS)

除了像深度優先遍歷這樣一頭扎到底的玩法以外,我們還有另一種玩法:首先把起點相鄰的幾個景點玩遍,然后去玩距離起點稍遠一些(隔一層)的景點,然后再去玩距離起點更遠一些(隔兩層)的景點......

在圖中,我們首先探索景點0的相鄰景點1、2、3、4:

?

接著,我們探索與景點0相隔一層的景點7、9、5、6:

?

最后,我們探索與景點0相隔兩層的景點8、10:

?

像這樣一層一層由內而外的遍歷方式,就叫做廣度優先遍歷(BFS)

?

深度/廣度優先遍歷 的實現

?

深度優先遍歷

首先說說深度優先遍歷的實現過程。這里所說的回溯是什么意思呢?回溯顧名思義,就是自后向前,追溯曾經走過的路徑。

我們把剛才游樂場的例子抽象成數據結構的圖,假如我們依次訪問了頂點0、1、7、8,發現無路可走了,這時候我們要從頂點8退回到頂點7。

而后我們探索了頂點10,又無路可走了,這時候我們要從頂點10退回到頂點7,再退回到頂點1。

?

像這樣的自后向前追溯曾經訪問過的路徑,就叫做回溯。

要想實現回溯,可以利用棧的先入后出特性,也可以采用遞歸的方式(因為遞歸本身就是基于方法調用棧來實現)。

下面我們來演示一下具體實現過程。

首先訪問頂點0、1、7、8,這四個頂點依次入棧,此時頂點8是棧頂:

從頂點8退回到頂點7,頂點8出棧:

接下來訪問頂點10,頂點10入棧:

從頂點10退到頂點7,從頂點7退到頂點1,頂點10和頂點7出棧:

?

探索頂點9,頂點9入棧:

以此類推,利用這樣一個臨時棧來實現回溯,最終遍歷完所有頂點。

廣度優先遍歷

接下來該說說廣度優先遍歷的實現過程了。剛才所說的重放是什么意思呢?似乎聽起來和回溯差不多?其實,回溯與重放是完全相反的過程。

仍然以剛才的圖為例,按照廣度優先遍歷的思想,我們首先遍歷頂點0,然后遍歷了鄰近頂點1、2、3、4:

接下來我們要遍歷更外圍的頂點,可是如何找到這些更外圍的頂點呢?我們需要把剛才遍歷過的頂點1、2、3、4按順序重新回顧一遍,從頂點1發現鄰近的頂點7、9;從頂點3發現鄰近的頂點5、6。

像這樣把遍歷過的頂點按照之前的遍歷順序重新回顧,就叫做重放。同樣的,要實現重放也需要額外的存儲空間,可以利用隊列的先入先出特性來實現。

下面我們來演示一下具體實現過程。

首先遍歷起點頂點0,頂點0入隊:

接下來頂點0出隊,遍歷頂點0的鄰近頂點1、2、3、4,并且把它們入隊:

然后頂點1出隊,遍歷頂點1的鄰近頂點7、9,并且把它們入隊:

然后頂點2出隊,沒有新的頂點可入隊:

以此類推,利用這樣一個隊列來實現重放,最終遍歷完所有頂點。

?

?
  • ?
  • /**
  • 圖的頂點
  • / private static class Vertex { int data; Vertex(int data) { this.data = data; } } /*
  • 圖(鄰接表形式)
  • / private static class Graph { private int size; private Vertex[] vertexes; private LinkedList adj[]; Graph(int size){ this.size = size; //初始化頂點和鄰接矩陣 vertexes = new Vertex[size]; adj = new LinkedList[size]; for(int i=0; i*
  • 深度優先遍歷
  • / public static void dfs(Graph graph, int start, boolean[] visited) { System.out.println(graph.vertexes[start].data); visited[start] = true; for(int index : graph.adj[start]){ if(!visited[index]){ dfs(graph, index, visited); } } } /*
  • 廣度優先遍歷
  • */
  • public static void bfs(Graph graph, int start, boolean[] visited, LinkedList queue) {
  • queue.offer(start);
  • while (!queue.isEmpty()){
  • int front = queue.poll();
  • if(visited[front]){
  • continue;
  • }
  • System.out.println(graph.vertexes[front].data);
  • visited[front] = true;
  • for(int index : graph.adj[front]){
  • queue.offer(index);;
  • }
  • }
  • }
  • public static void main(String[] args) {
  • Graph graph = new Graph(6);
  • graph.adj[0].add(1);
  • graph.adj[0].add(2);
  • graph.adj[0].add(3);
  • graph.adj[1].add(0);
  • graph.adj[1].add(3);
  • graph.adj[1].add(4);
  • graph.adj[2].add(0);
  • graph.adj[3].add(0);
  • graph.adj[3].add(1);
  • graph.adj[3].add(4);
  • graph.adj[3].add(5);
  • graph.adj[4].add(1);
  • graph.adj[4].add(3);
  • graph.adj[4].add(5);
  • graph.adj[5].add(3);
  • graph.adj[5].add(4);
  • System.out.println("圖的深度優先遍歷:");
  • dfs(graph, 0, new boolean[graph.size]);
  • System.out.println("圖的廣度優先遍歷:");
  • bfs(graph, 0, new boolean[graph.size], new LinkedList());
  • }
  • ?

    以上內容來自《漫畫算法》

    </div>

    總結

    以上是生活随笔為你收集整理的数据结构-深度优先遍历和广度优先遍历(漫画)的全部內容,希望文章能夠幫你解決所遇到的問題。

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