算法基礎:BFS和DFS的直觀解釋
一、前言
我們首次接觸 BFS 和 DFS 時,應該是在數據結構課上講的 “圖的遍歷”。還有就是刷題的時候,遍歷二叉樹我們會經常用到BFS和DFS。它們的實現都很簡單,這里我就不哆嗦去貼代碼了。
想看代碼的可以看《劍指Offer(三十八):二叉樹的深度》這個題目就可以利用BFS和DFS進行求解。那么,這兩者“遍歷” 的序列到底有何差別?
本篇文章就單純來講講它們的區別和各自的應用,不會涉及任何代碼。我們以“圖的遍歷”為例,進行說明。
二、區別
廣度優先搜索算法(Breadth-First-Search,縮寫為 BFS),是一種利用隊列實現的搜索算法。簡單來說,其搜索過程和 “湖面丟進一塊石頭激起層層漣漪” 類似。
深度優先搜索算法(Depth-First-Search,縮寫為 DFS),是一種利用遞歸實現的搜索算法。簡單來說,其搜索過程和 “不撞南牆不回頭” 類似。
BFS 的重點在於隊列,而 DFS 的重點在於遞歸。這是它們的本質區別。
舉個典型例子,如下圖,灰色代表牆壁,綠色代表起點,紅色代表終點,規定每次只能走一步,且只能往下或右走。求一條綠色到紅色的最短路徑。
對於上面的問題,BFS 和 DFS 都可以求出結果,它們的區別就是在復雜度上存在差異。我可以先告訴你,該題 BFS 是較佳算法。
BFS示意圖:
如上圖所示,從起點出發,對於每次出隊列的點,都要遍歷其四周的點。所以說 BFS 的搜索過程和 “湖面丟進一塊石頭激起層層漣漪” 很相似,此即 “廣度優先搜索算法” 中“廣度”的由來。
DFS示意圖:
如上圖所示,從起點出發,先把一個方向的點都遍歷完才會改變方向...... 所以說,DFS 的搜索過程和 “不撞南牆不回頭” 很相似,此即 “深度優先搜索算法” 中“深度”的由來。
三、總結
現在,你不妨對照着圖,再去看看你打印出的遍歷序列,是不是一目了然呢?
最后再說下它們的應用方向。
BFS 常用於找單一的最短路線,它的特點是 "搜到就是最優解",而 DFS 用於找所有解的問題,它的空間效率高,而且找到的不一定是最優解,必須記錄並完成整個搜索,故一般情況下,深搜需要非常高效的剪枝(剪枝的概念請百度)。
PS:BFS 和 DFS 是很重要的算法,讀者如果想要更深入地了解它們,建議去 OJ 或 Leetcode 上找一些相關賽題訓練下,一定會給你一個別樣的天地。