欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

BFS与DFS总结

程序员文章站 2022-06-12 09:18:39
...

BFS与DFS总结

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显然更加合适。