圖的遍歷——BFS 與 DFS 深度優先和廣度優先搜索|圖論算法

問題引入

有一天,你穿越到Clannad(炒雞好看的遊戲與番劇)的小鎮。你知道小鎮上的每個地方與每條路。小鎮的某些地方可能會藏有實現願望的光玉。現在你要出發去收集小鎮上所有的光玉。

如圖:

假設小鎮中一個地方對應這張圖的一個結點,你的出生點在古河面包店(0號位置),據題意,你需要一個地點都不落地走完整張圖,這樣才能收集完所有光玉。

BFS

廣度優先搜索(Breadth First Search):

屬於一層一層地擴展,每次到一個點後,把這個點其他相鄰點都記錄下來,作爲下一層的待訪問結點。

根據這個概念,我們需要準備:

一個小本本

步驟:

1、每到達一個點(最開始是起點),觀望一下週圍哪些地點跟當前點相連,把這些點都添加在小本本上。

2、跳到小本本上記錄的第一個地點(執行 1 步驟),然後把這個地點從小本本上擦除。

3、重複執行 2、直到小本本上沒有記錄任何點(此時已經到達了所有地點,後面有實例將證明)

根據上面的步驟,可以給出僞代碼:

僞代碼:把起點添加到小本本上;while (小本本上 有 地點) {跳到小本本上最上面的地點,假設爲P點。 把P點從小本本上擦除。for ( 遍歷所有 與P點相鄰 的Q點 ) { if ( Q點不在小本本上 ) { 把 Q點 添加到小本本的最後面。 } }}

可以看出:小本本具有先進先出的性質,就是一個隊列

把 0點 記在小本本上。

從小本本中取出 0點(到達 0點 ), 觀望一下,把1點、2點、7點記錄在小本本上。這時小本本上 記錄了1點、2點、7點。

(1點在前)從小本本中取出 1點,觀望一下,把 4點、5點記錄在小本本上。這時小本本上 記錄了2點、7點、4點、5點。

從小本本中取出 2點,觀望一下,把 4點 已經在小本本上了,不用記錄。這時小本本上 記錄了7點、4點、5點。

從小本本中取出 7點,觀望一下,沒有可以記錄的點。這時小本本上 記錄了4點、5點。

從小本本中取出 4點,觀望一下,把 3點 記錄在小本本上。這時小本本上 記錄了5點、3點。

從小本本中取出 5點,觀望一下,把 6點 記錄在小本本上。這時小本本上 記錄了3點、6點。

從小本本中取出 3點,觀望一下,沒有可以記錄的點。這時小本本上 記錄了6點。

從小本本中取出 6點,觀望一下,沒有可以記錄的點。小本本已經沒有記錄任何點了,同時所有地點都走完啦。

DFS

深度優先搜索(Depth First Search):

先選擇一條路一直往前走,走到盡頭後,就返回到上一個交叉路口選擇另一條沒走過的路。

一直重複,這樣就能走完所有的地點。

(像不像老鼠走迷宮,一條路一條路地嘗試)

根據這個尋路的過程,我們要知道:

每個結點能去到哪些其他結點。怎樣返回到上一個交叉路口。關於返回到上一個路口,我們很容易想到遞歸。

遞歸的過程是 走到每一個相鄰的結點

遞歸的邊界是 走到盡頭(即沒有能走的結點 或者 每一個相鄰結點都走完了)

下面是僞代碼:

到達( P點 ){for( 從P點出發能去的相鄰的點Q ){ if( 沒有來過Q點 ){記錄Q點到過了。 到達( Q點 ) } } 返回P點前的一步}

解析:

遞歸函數: 到達(某點)

遞歸函數結束:當for循環(遍歷所有能去的結點)結束

一條路已經走完了,返回到上一個交叉路口。

過程:

據說 下面的過程跟上面的圖更配哦

1.從起點出發,進入遞歸函數——>到達0點

(到達0點)有1點 2點 7點相鄰。從編號最小的開始。進入 ——到達1點

(到達0點 (到達1點)) 有 4點 5點相鄰。 進入——到達4點(到達0點 (到達1點 (到達4點))有2點 3點 相鄰。進入——到達2點

(到達0點 (到達1點 (到達4點 (到達2點)))這時0點訪問過,這條路到盡頭了,返回上一個路口——到達4點此時走完了 0——1——4——2 這條路

(到達0點 (到達1點 (到達4點))有2點 3點 相鄰。2點訪問過,進入——到達3點

(到達0點 (到達1點 (到達4點 (到達3點))這條路到盡頭了,返回上一個路口——到達4點此時走完了 0——1——4——3 這條路

(到達0點 (到達1點 (到達4點))這條路到盡頭了,返回上一個路口——到達1點此時走完了 0——1——4 這條路

(到達0點 (到達1點)) 有 4點 5點相鄰。4點訪問過了。 進入——到達5點

(到達0點 (到達1點 (到達5點))有6點相鄰。進入——到達6點

(到達0點 (到達1點 (到達5點 (到達6點))這條路到盡頭了,返回上一個路口——到達5點此時走完了0——1——5——6

(到達0點 (到達1點 (到達5點))這條路到盡頭了,返回上一個路口——到達1點走完了0——1——5

(到達0點 (到達1點))這條路到盡頭了,返回上一個路口——到達0點走完了0——1

(到達0點)有1點 2點 7點相鄰。1點2點都訪問過了,進入——到達7點

(到達0點 (到達7點))這條路到盡頭了,返回上一個路口——到達0點走完了0——7

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章