遍历搜索
- 访问每一个节点
- 每个节点仅仅访问一次
- 搜索的顺序
- 深度搜索
- 广度搜索
- 优先级搜索 启发式搜索 适用的场景
DFS
DFS遍历顺序-二叉树
走的顺序
- 先从根开始
- 走最左边的
- 走中间的
- 走右边的
DFS遍历顺序-图
假设从S节点开始触发
走的顺序 S(岔路) A(假设先走A 走B C都是一样的 随便挑一个就行) D G(岔路) E(假设先走的E 走E 走F都一样) B S(发现S已经访问过了 返回上一个岔路G) F C S(发现已经访问过了 就继续回)
DFS代码模版-递归写法
写法1
def dfs(node):
# 终止条件
if node in visited: # terminator
# already visited
return
# 当前层的处理逻辑
visited.add(node)
# 下探到下一层
dfs(node.left)
dfs(node.right)
写法2 当前层 没有走完 会继续进入下一次 同样下一层也没走完 又继续下探到 下下层去了
visited = set()
def dfs(node, visited):
# 终止条件
if node in 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)
# 需要先传入root根节点
dfs(root_node)
DFS代码模版-非递归写法
手动维护一个栈 去记录已经处理过的节点 和 未处理过的节点
def DFS(self, tree):
if tree.root is None:
return []
# visited 定义已经访问过的元素
# stack 放入待处理的元素
visited , stack = [], [tree.root]
while stack:
node = stack.pop()
visited.add(node)
# 处理元素
process (node)
# 向下挖掘出它的关联节点 放到栈中 继续处理
nodes = generate_related_nodes(node)
stack.push(nodes)
# other processing work
...
BFS(广度搜索)
广度搜索 使用的是队列 每一层想象成一个水波纹 这个平面落一滴水 一直扩散出去 铺满整个平面
广度遍历顺序-二叉树
BFS代码模版-非递归写法
def BFS(graph, start, end):
# 放入已经访问的元素
visited = set()
# 队列中放入未访问的元素 (可以使用双端队列)
queue = []
queue.append([start])
while queue:
node = queue.pop()
visited.add(node)
process(node)
# 找到关联节点 扩散出他的周围节点 继续加入队列
# 类似一个ceo 找到他下面所有的vp 然后把所有的vp塞入队列
nodes = generate_related_nodes(node)
queue.push(nodes)
# other processing work
...