本文始发于个人公众号:TechFlow,原创不易,求个关注
在之前周末LeetCode专栏当中,我们详细描述了深度优先搜索和回溯法,所以今天我们继续这个话题,来和大家聊聊搜索算法的另一个分支,广度优先搜索。
广度优先搜索的英文是Breadth First Search,简写为bfs。与它相对的深度优先搜索,英文自然就是Depth First Search,简写成dfs。所以如果在阅读我或者其他人的代码时发现有个函数叫做bfs或者dfs,如果你能回忆起这些英文缩写,一定可以明白它们是什么意思。
bfs与dfs
在讲解bfs的概念之前,我们先来回顾一下dfs的概念,好有个对比。
通过之前的文章,我们已经知道了实现dfs往往需要使用递归。我们在一次递归当中需要遍历当前所有的决策,然后递归去执行这些决策。如果这些决策会对未来的决策产生影响,那么我们还需要使用回溯法,在决策遍历结束之后,撤销当前的操作。
所以我们有了dfs的模板代码:
def dfs(n):
if n > depth:
return
for i in decisions:
do_decision(i)
dfs(n+1)
rollback(i)
假如我们有一棵树,我们需要遍历树。显然由于树是由节点组成的树形结构,不是list结构,所以我们并不能直接用循环来遍历。为了避免重复,我们需要按照一定的顺序在树上遍历。最常用的就是使用dfs和bfs,我们先来看一下dfs怎么解决这个问题。
套用一下上面的模板,我们可以很容易写出来:
def dfs(node):
if node is None:
return
for child in node.childs:
print(child)
dfs(child)
由于我们只需要遍历节点,遍历的过程并不会对后面的遍历产生影响,所以我们不需要rollback这一步。并且树天然有结构,我们递归的顺序刚好和树本身的顺序一致,都是从父节点往子节点遍历。所以并不需要其他的处理。
假如我们有这样一棵树: