bfs(廣度優先遍歷,breadth first search)及dfs(深度優先遍歷,depth first search)是遍歷樹或圖的兩種最常用的方法。本文簡單的講解在面對樹或者圖的問題時,使用bfs及dfs解答題目時的思路及實現。
根據上圖就可以很清晰的理解出bfs的概念,即一層一層的遍歷。在使用bfs解決問題的時候最先想到的方式應該是佇列(queue,fifo)
其主要思想是從起始點開始,將其鄰近的所有頂點都加到乙個佇列(fifo)中去,然後標記下這些頂點離起始頂點的距離為1.最後將起始頂點標記為已訪問,今後就不會再訪問。然後再從佇列中取出最先進隊的頂點a,也取出其周邊鄰近節點,加入佇列末尾,最後離開這個頂點a。依次下去,直到隊列為空為止。從上面描述的過程我們知道每個頂點被訪問的次數最多一次(已訪問的節點不會再訪問)。
**:首先定義二叉樹:
//definition for a binary tree node.
public class treenode
}
使用佇列實現bfs遍歷二叉樹:
//使用queue實現bfs
上圖可以看出dfs是如何工作的,使用dfs解決問題時最先想到的應該是遞迴和棧(stack)dfs是從起始頂點開始,遞迴訪問其所有鄰近節點,比如a節點是其第乙個鄰近節點,而b節點又是a的乙個鄰近節點,則dfs訪問a節點後再訪問b節點,如果b節點有未訪問的鄰近節點的話將繼續訪問其鄰近節點,否則繼續訪問a的未訪問鄰近節點,當所有從a節點出去的路徑都訪問完之後,繼續遞迴訪問除a以外未被訪問的鄰近節點。
使用遞迴實現dfs遍歷二叉樹:(優先選擇)
//dfs遞迴實現
public void dfswithrecursion(treenode root)
使用stack實現dfs
//dfs的迭代實現版本(stack)
public void dfswithstack(treenode root)
}
以上三種方法都將數中每個節點遍歷一遍,時間複雜度為o(n)。
樹結構:
// definition for a node.
class node
public node(int _val,list_children)
};
bfs及dfs只需將上述**用for迴圈替代
圖和樹的最大區別在於圖的下乙個節點可能指向已訪問過的節點。因此在使用bfs及dfs遍歷時,應維護乙個set,set中存放已被訪問過的節點,在遍歷時先判斷節點未被訪問過再遍歷即可。
使用bfs舉例如下:
//使用queue實現bfs
public void bfswithqueue(node root) }}
}}
follow my github: BFS和DFS詳解以及java實現
圖在演算法世界中的重要地位是不言而喻的,曾經看到一篇google的工程師寫的一篇 get that job at google 文章中說到面試官問的問題中幾乎有一半的問題都可以用圖的方法去解決。由此也可以看出圖確實適用範圍確實很廣。閒話不多說,首先要介紹的就是圖的表示,圖最常用的兩種表示方法是鄰接表...
演算法 dfs和bfs的演算法實現
bfs主要應用於連通圖的遍歷,它的核心思想是從乙個頂點開始,輻射狀地優先遍歷其周圍較廣的區域,即逐層遍歷,bfs最經典的應用場景為最短路徑,很多最短路徑演算法都是基於bfs實現,bfs通常基於佇列的思想實現,其實現過程如下 1 頂點入佇列 2 隊列為空,演算法結束,佇列非空,演算法繼續執行 3 出佇...
BFS和DFS的差別 BFS實現迷宮最短路徑
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!bfs能夠求得最短路徑,因為bfs每進行一次相當於當前的路徑長度。對於乙個n n矩陣,bfs最多執行n n次。深度優先搜尋相當於乙個人在走迷宮,廣搜相當於是無窮人沿著不同方向走 因為每條路都同時有人走 dfs相當於是乙個下壓棧。是先進後出的原則 如...