dfs前置知識:
遞迴連結:0基礎演算法基礎學演算法 第六彈 遞迴 - 球君 - 部落格園 (cnblogs.com)
dfs深度優先搜尋:0基礎學演算法 搜尋篇第一講 深度優先搜尋 - 球君 - 部落格園 (cnblogs.com)
本講前置知識:
佇列:0基礎學演算法 第三彈 佇列 - 球君 - 部落格園 (cnblogs.com)
↑早期作品,慎用↑
我們在上一講稍微說了一下關於深度優先搜尋的常識,今天我們的主題是廣度優先搜尋
廣度優先搜尋,簡稱BFS,同dfs一樣,屬於十分常見的演算法,也是最常用的搜尋方法之一,由於思路和dfs完全不同,這也導致了它們在性質和作用上的不同,接下來,我們來結合上一講的部分例子,說一說廣度優先搜尋的順序與使用方法。
還記得這張圖嗎(2020/11/1的產物)
一、BFS的演算法思想
在dfs中,由於我們會選擇從原始節點沿一條搜尋路線找到底部的節點,再從底部節點回溯到上一個節點繼續看有沒有更多可能,這書使用了遞迴
在bfs中,我們會在初始節點處開始往下尋找,找到它的所有子目錄節點,再尋找它子目錄下的所有子目錄節點,從此達成遍歷,請看以下過程
第一步要確定搜尋起點,即原始節點,從這裡開始搜尋
從①往下找自然可以找到②
從①往下還可以找到⑩
目前我們對這張圖的遍歷順序:①→②→⑩→③→⑦→⑧
搜尋順序追蹤:①→②→⑩→③→⑦→⑧→④→⑤→⑨
最後從⑤找到了⑥,由於再也找不到任何一個了,此時所有節點都以找到,搜尋結束
一般來講,dfs會使用到遞迴,而bfs不需要,這和它的中心思想有關,dfs需要不斷挖深,挖到底還需要往上爬,但根據剛剛bfs的搜尋順序圖,不難看出bfs在到底後搜尋就結束了,所以說bfs不需要用到遞迴,只需要用到普通的迴圈。
但是,怎樣才能做到依次載入一個節點的每一個子節點,然後繼續依次載入它的子節點的子節點呢?
二、佇列實現BFS
佇列是實現BFS最常用的方法,我個人比較喜歡使用c++標準模板庫STL中的“佇列”queue(stl佇列介紹:見篇首)不過使用手打的佇列也無傷大雅。
總的來說,原理就是載入初始節點,再將它的子節點全部載入,彈出他,從第一個子節點開始,載入子節點的子節點們,彈出子節點……
舉了例子,有如下圖
那麼我們使用BFS時,佇列裡是什麼情況呢
建立佇列後壓入頭節點
壓入頭節點的子節點
彈出頭節點
壓入第一個子節點的所有子節點
如圖
接下來重複以上操作,直到佇列彈空
由於接下來的③⑦⑧⑤⑥均沒有子節點了,所以搜尋結束,所有節點完成遍歷。
本期的內容差不多到這裡就結束了,關於程式碼實現的問題,敬請期待下一期BFS廣度優先搜尋的實現與實踐,記得點贊關注!