BFS和DFS詳解以及java實現

2021-08-30 15:40:44 字數 1796 閱讀 3618

圖在演算法世界中的重要地位是不言而喻的,曾經看到一篇google的工程師寫的一篇《get that job at google!》文章中說到面試官問的問題中幾乎有一半的問題都可以用圖的方法去解決。由此也可以看出圖確實適用範圍確實很廣。

閒話不多說,首先要介紹的就是圖的表示,圖最常用的兩種表示方法是鄰接表和鄰接矩陣。顧名思義,這兩種辦法分別用表和矩陣的方式描述圖中各頂點之間的聯絡

下圖展示了兩種表示上面這個圖的方法

本文將著重介紹遍歷圖的兩種最常用的方法,分別為廣度優先遍歷和深度優先遍歷,後面會具體介紹為什麼這麼命名。首先來看廣度優先遍歷bfs(breadth first search),其主要思想是從起始點開始,將其鄰近的所有頂點都加到乙個佇列(fifo)中去,然後標記下這些頂點離起始頂點的距離為1.最後將起始頂點標記為已訪問,今後就不會再訪問。然後再從佇列中取出最先進隊的頂點a,也取出其周邊鄰近節點,加入佇列末尾,將這些頂點的距離相對a再加1,最後離開這個頂點a。依次下去,直到隊列為空為止。從上面描述的過程我們知道每個頂點被訪問的次數最多一次(已訪問的節點不會再訪問),而對於連通圖來說,每個頂點都會被訪問。加上每個頂點的鄰接鍊錶都會被遍歷,因此bfs的時間複雜度是θ(v+e),其中v是頂點個數,e是邊數,也就是所有鄰接表中的元素個數。為了更好的說明這個過程,下圖列出了對乙個圖的bfs的過程

}執行結果:

從執行結果我們也可以看到,w r作為距離為1的頂點先被訪問,x t v其後,最後訪問y u。上面的**使用了乙個小的trick,用dist這個hash表來記錄每個頂點離s的距離,如果dist中沒有這個元素則說明還未被訪問,這時將距離寫入dist中。bfs訪問得到的每個節點與起始頂點的距離是起始頂點到達該頂點的最短距離。從感性認識上來說,bfs向外擴散的方式得到的距離就是最短距離。詳細的證明過程請參考clrs上的相應章節

如下是dfs的**及執行結果

private static void dfs(hashmap> graph,hashmapvisited)

private static void visit(hashmap> graph,hashmapvisited,char start)

}count++;

system.out.println("the time out element "+start+":"+count);//記錄離開該節點的時間}}

執行結果:

我們通過乙個全域性變數count記錄了進入每個節點和離開每個節點的時間,我們也可以看到進出元素的時間和過程圖中的訪問過程是一樣的。

總的來說,bfs多用於尋找最短路徑的問題,dfs多用於快速發現底部節點。以後若有時間再貼幾道相關的題目上來。

DFS和BFS演算法

本質區別 bfs 的重點在於佇列,而 dfs 的重點在於遞迴。這是它們的本質區別。dfs 演算法 是一種利用遞迴 實質上是用棧來儲存未訪問的結點,先進後出 實現的搜尋演算法,直到找到解或走不下去為止。簡單來說,其搜尋過程和 不撞南牆不回頭 樹的先序遍歷 類似。bfs演算法 是一種利用佇列 用佇列來儲...

DFS和BFS演算法

一 深度優先遍歷 深度優先搜尋,是圖論中的經典演算法。其利用深度優先搜尋演算法可以產生目標圖的相應拓撲排序表,利用拓撲排序表可以方便的解決很多相關的圖論問題,如最大路徑問題等等。遞迴定義 圖的深度優先遍歷類似於樹的前序遍歷。採用的搜尋方法的特點是盡可能先對縱深方向進行搜尋。這種搜尋方法稱為深度優先搜...

BFS及DFS的Java實現

bfs 廣度優先遍歷,breadth first search 及dfs 深度優先遍歷,depth first search 是遍歷樹或圖的兩種最常用的方法。本文簡單的講解在面對樹或者圖的問題時,使用bfs及dfs解答題目時的思路及實現。根據上圖就可以很清晰的理解出bfs的概念,即一層一層的遍歷。在...