BFS与DFS总结
程序员文章站
2022-06-12 09:18:39
...
BFS与DFS总结
BFS与DFS基本操作与知识:
深度优先搜索是一个不断回溯的过程。
广度优先搜索是一层层遍历的过程。
BFS模板:
BFS 使用队列,把每个还没有搜索到的点依次放入队列,然后再弹出队列的头部元素当做当前遍历点。BFS 总共有两个模板:
- 如果不需要确定当前遍历到了哪一层,BFS 模板如下:
while queue 不空:
cur = queue.pop()
for 节点 in cur的所有相邻节点:
if 该节点有效且未访问过:
queue.push(该节点)
- 如果要确定当前遍历到了哪一层,BFS 模板如下:
这里增加了 level 表示当前遍历到二叉树中的哪一层了,也可以理解为在一个图中,现在已经走了多少步了。size 表示在当前遍历层有多少个元素,也就是队列中的元素数,我们把这些元素一次性遍历完,即把当前层的所有元素都向外走了一步。
level = 0
while queue 不空:
size = queue.size()
while (size --) {
cur = queue.pop()
for 节点 in cur的所有相邻节点:
if 该节点有效且未被访问过:
queue.push(该节点)
}
level ++;
DFS模板:
DFS使用的栈实现的,一般有两种方式,一种是用递归其实就是隐性的使用系统栈,另一种是使用的工具栈实现dfs模拟递归的方式。
- DFS十分的简洁灵活,在使用DFS时递归式需要注意:
1.递归函数中需要哪些形参,有需要还可以使用全局变量提高灵活性 2.终止条件 3.继续递归的条件
dfs(一些必要的形参)
{
if判断边界
{
相应操作
}
for(循环)尝试每一种可能
{
if条件{
标记
继续下一步dfs(形参要做出改变)
}
恢复初始状态(回溯的时候要用到)
}
}
- 使用工具栈的方式(注意何时入栈,何时出栈与相应的条件判断):
工具栈stack的创建
加入一些初始数据到栈中
while判断栈是否为空或加一些其它的判断{
while判断通过就向一个方向不断的深入 {
数据加入stack
相关操作
}
stack进行出栈回溯
相关操作
}
以下是一些LeetCode的例题:
岛屿数量,完全平方数 ,二叉树的中序遍历,打开转盘锁,墙与门
BFS与DFS的用途与选择
1.BFS是用来搜索最短径路的解是比较合适的,比如求最少步数的解,最少交换次数的解,因为BFS搜索过程中遇到的解一定是离根最近的,所以遇到一个解,一定就是最优解,此时搜索算法可以终止。这个时候不适宜使用DFS,因为DFS搜索到的解不一定是离根最近的,只有全局搜索完毕,才能从所有解中找出离根的最近的解。(当然这个DFS的不足,可以使用迭代加深搜索ID-DFS去弥补)
2.空间优劣上,DFS是有优势的,DFS不需要保存搜索过程中的状态,而BFS在搜索过程中需要保存搜索过的状态,而且一般情况需要一个队列来记录。
3.DFS适合搜索全部的解,因为要搜索全部的解,那么BFS搜索过程中,遇到离根最近的解,并没有什么用,也必须遍历完整棵搜索树,DFS搜索也会搜索全部,但是相比DFS不用记录过多信息,所以搜素全部解的问题,DFS显然更加合适。
上一篇: BFS知识点总结
下一篇: 【总结】DFS和BFS模板总结及例题详解