廣度優先搜尋(bfs)的乙個常見應用是找出從根結點到目標結點的最短路徑。
這裡我們提供乙個示例來說明如何使用 bfs 來找出根結點a
和目標結點g
之間的最短路徑。
**上面的動畫後,讓我們回答以下問題:
1. 結點的處理順序是什麼?
在第一輪中,我們處理根結點。在第二輪中,我們處理根結點旁邊的結點;在第三輪中,我們處理距根結點兩步的結點;等等等等。
與樹的層序遍歷類似,越是接近根結點的結點將越早地遍歷
。
如果在第 k 輪中將結點x
新增到佇列中,則根結點與x
之間的最短路徑的長度恰好是k
。也就是說,第一次找到目標結點時,你已經處於最短路徑中。
2. 佇列的入隊和出隊順序是什麼?
如上面的動畫所示,我們首先將根結點排入佇列。然後在每一輪中,我們逐個處理已經在佇列中的結點,並將所有鄰居新增到佇列中。值得注意的是,新新增的節點不會
立即遍歷,而是在下一輪中處理。
結點的處理順序與它們新增
到佇列的順序是完全相同的順序
,即先進先出(fifo)。這就是我們在 bfs 中使用佇列的原因。
與 bfs 類似,深度優先搜尋
(dfs)也可用於查詢從根結點到目標結點的路徑。在本文中,我們提供了示例來解釋 dfs 是如何工作的以及棧是如何逐步幫助 dfs 工作的。
我們來看乙個例子吧。我們希望通過 dfs 找出從根結點a
到目標結點g
的路徑。
**上面的動畫後,讓我們回答以下問題:
1. 結點的處理順序是什麼?
在上面的例子中,我們從根結點a
開始。首先,我們選擇結點b
的路徑,並進行回溯,直到我們到達結點e
,我們無法更進一步深入。然後我們回溯到a
並選擇第二條路徑到結點c
。從c
開始,我們嘗試第一條路徑到e
但是e
已被訪問過。所以我們回到c
並嘗試從另一條路徑到f
。最後,我們找到了g
。
總的來說,在我們到達最深的
結點之後,我們只
會回溯並嘗試另一條路徑。
因此,你在 dfs 中找到的第一條路徑並不總是最短的路徑。例如,在上面的例子中,我們成功找出了路徑2. 棧的入棧和退棧順序是什麼?如上面的動畫所示,我們首先將根結點推入到棧中;然後我們嘗試第乙個鄰居a-> c-> f-> g
並停止了 dfs。但這不是從a
到g
的最短路徑。
b
並將結點b
推入到棧中;等等等等。當我們到達最深的結點e
時,我們需要回溯。當我們回溯時,我們將從棧中彈出最深的結點
,這實際上是推入到棧中的最後乙個結點
。
結點的處理順序是完全相反的順序
,就像它們被新增
到棧中一樣,它是後進先出(lifo)。這就是我們在 dfs 中使用棧的原因。
bfs:廣度優先搜尋
dfs:深度優先搜尋
歡迎關注微.信公.眾號:愛寫bug
DFS和BFS演算法
本質區別 bfs 的重點在於佇列,而 dfs 的重點在於遞迴。這是它們的本質區別。dfs 演算法 是一種利用遞迴 實質上是用棧來儲存未訪問的結點,先進後出 實現的搜尋演算法,直到找到解或走不下去為止。簡單來說,其搜尋過程和 不撞南牆不回頭 樹的先序遍歷 類似。bfs演算法 是一種利用佇列 用佇列來儲...
DFS和BFS演算法
一 深度優先遍歷 深度優先搜尋,是圖論中的經典演算法。其利用深度優先搜尋演算法可以產生目標圖的相應拓撲排序表,利用拓撲排序表可以方便的解決很多相關的圖論問題,如最大路徑問題等等。遞迴定義 圖的深度優先遍歷類似於樹的前序遍歷。採用的搜尋方法的特點是盡可能先對縱深方向進行搜尋。這種搜尋方法稱為深度優先搜...
迷宮求解演算法(棧DFS以及佇列BFS)
我們首先給出乙個迷宮,它的規格是5 5,在這裡我使用int的二維陣列表示迷宮,其中1表示障礙,0表示可以通行的道路,要求從 0,0 座標走到 4,4 座標,並輸出走過的座標路徑。int maze 5 5 使用棧來實現dfs 深度優先搜尋 首先,我們給出棧在迷宮中的的結構定義。x是迷宮中的橫座標 y是...