定義
深度優先搜索算法(Depth-First-Search),是搜索算法的一種。它沿着樹的深度遍歷樹的節點,盡可能深的搜索樹的分支。
例如下圖,其深度優先遍歷順序為 1->2->4->8->5->3->6->7
算法步驟
- 訪問頂點v;
- 依次從v的未被訪問的鄰接點出發,對圖進行深度優先遍歷;直至圖中和v有路徑相通的頂點都被訪問;
- 若此時圖中尚有頂點未被訪問,則從一個未被訪問的頂點出發,重新進行深度優先遍歷,直到圖中所有頂點均被訪問過為止。
算法模板
# Python 遞歸寫法
visited = set()
def dfs(node, visited):
if node in visited: # terminator
# already visited
return
visited.add(node)
# process current node here.
...
for next_node in node.children():
if next_node not in visited:
dfs(next_node, visited)
# 非遞歸寫法
def DFS(self, root):
if tree.root is None:
return []
visited, stack = [], [root]
while stack:
node = stack.pop()
visited.add(node)
process (node)
# 生成相關的節點
nodes = generate_related_nodes(node)
stack.push(nodes)
# other processing work
...
// Golang 遞歸寫法
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
var visited map[*TreeNode]bool = make(map[*TreeNode]bool)
func dfs(node *TreeNode, visited *map[*TreeNode]bool) {
if _,ok:= (map[*TreeNode]bool)visited[node]; ok { // terminator
// already visited
return
}
(map[*TreeNode]bool)visited[node] = true
// process current node here
...
for _,next_node := range node.children() {
if _,ok := (map[*TreeNode]bool)visited[next_node]; !ok{
dfs(next_node, visited)
}
}
}
// 非遞歸寫法
func DFS(root *TreeNode) {
if root == nil {
return
}
visited := make(map[*TreeNode]bool)
stack := make([]*TreeNode, 0)
stack = append(stack, root)
for len(stack) > 0 {
node = stack[len(stack)-1]
stack = stack[:len(stack)-1]
visited[node] = true
process(node)
// 生成相關的節點
nodes = generate_related_nodes(node)
stack.push(nodes)
}
// other processing work
}
要點
- 使用棧 stack
- 記錄已訪問節點 visited ,通常使用哈希表
適用場景
- 樹
- 圖
- 二維數組