深度優先搜索 廣度優先搜索理解

                                     深度優先搜索廣度優先搜索

1. 什麼是 “搜索” 算法

我們知道,算法都是作用於某種具體的數據結構上的,而深度優先搜索算法和廣度優先搜索算法就是作用於圖這種數據結構的。

圖上的搜索算法,就是從圖中的一個頂點出發,到另一個頂點的路徑。圖有兩種存儲方法,鄰接矩陣和鄰接表,在這裏我們用鄰接表來存儲圖,並以無向圖作爲例子,但這兩種算法也同樣都可以應用在有向圖中。

V 爲頂點個數,E 爲邊的條數。

 

深度優先搜索

深度優先搜索(Depth-First-Search),簡稱 DFS,最直觀的例子就是走迷宮。

假設你站在迷宮的某個分岔路口,你想找到出口。你隨意選擇一個岔路口來走,走着走着發現走不通的時候就原路返回到上一個分岔路口,再選擇另一條路繼續走,直到找到出口,這種走法就是深度優先搜索的策略。

上圖中,我們希望找到一條從 s 到 t 的路徑,其中實線表示向前遍歷,虛線表示回退。可以看到,深度優先搜索到的並不是從 s 到 t 的最短路徑。

 

實際上,深度優先搜索用的是一種比較著名的思想——回溯思想,這種思想非常適合用遞歸來實現。深度優先搜索的代碼裏面有幾個和廣度優先搜索一樣的部分 visited、prev 和 Print() 函數,它們的作用也都是一樣的。此外,還有一個特殊的 found 變量,標記是否找到終止頂點,找到之後我們就可以停止遞歸不用再繼續查找了。

 

在深度優先搜索算法中,每條邊最多會被訪問兩次,一次是遍歷,一次是回退。所以,深度優先搜索的時間複雜度爲 O(E)。

visited、prev 數組的大小爲頂點個數,而遞歸函數調用棧的最大深度不會超過頂點的個數,所以深度優先搜索的空間複雜度爲 O(V)。

廣度優先搜索

廣度優先搜索(Breadth-First-Search),一般簡稱爲 BFS。直觀地講,它其實就是一種地毯式層層推進的搜索策略,即先查找離起始頂點最近的,然後是次近的,依次往外搜索。

下面我們來看一下廣度優先搜索的時間複雜度和空間複雜度。

最壞情況下,終止頂點 t 距離起始頂點 s 很遠,需要遍歷完整個圖才能找到。這時候,每個頂點都要進出一遍隊列,每條邊也都會被訪問一次。所以,廣度優先搜索的時間複雜度爲 O(V+E),V 爲頂點個數,E 爲邊的條數。針對一個所有頂點都是聯通的圖,E 肯定要大於 V-1,所以時間複雜度可以簡寫爲 O(V)。

 

空間複雜度主要是三個變量所佔用的額外空間,和頂點個數成正相關,爲 O(V)。

 

其中,有三個非常重要的輔助變量需要特別注意。

  • visited,布爾數組,記錄頂點是否已經被訪問過,訪問過則爲真,沒有訪問過則爲假,這裏用 0 和 1 表示。
  • vertex,記錄上一層的頂點,也即已經被訪問但其相連的頂點還沒有被訪問的頂點。當一層的頂點搜索完成後,我們還需要通過這一層的頂點來遍歷與其相連的下一層頂點,這裏我們用隊列來記錄上一層的頂點。
  • prev,記錄搜索路徑,保存的是當前頂點是從哪個頂點遍歷過來的,比如 prev[4] = 1,說明頂點 4 是通過頂點 1 而被訪問到的。

參考文獻

https://zhuanlan.zhihu.com/p/95081559

 

https://blog.csdn.net/curry___/article/details/81742727

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