BFS算法介绍

定义:

广度优先算法(Breadth-First-Search),简称BFS,是一种图形搜索演算法。简单的说,BFS是从根节点开始,沿着树的宽度遍历树的节点,如果发现目标,则演算终止


算法分析:

BFS是一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。


时间复杂度:邻接表的时候是O(|V| + |E|)。其中 |V| 是节点的数目,|E| 是图中边的数目。

——以上内容主要来自度娘

适用条件:

对于所有边长度相同的情况,比如地图的模型,bfs第一次遇到目标点,此时就一定是从根节点到目标节点最短的路径(因为每一次所有点都是向外扩张一步,你先遇到,那你就一定最短)。bfs先找到的一定是最短的。但是如果是加权边的话这样就会出问题了,bfs传回的是经过边数最少的解,但是因为加权了,这个解到根节点的距离不一定最短。比如1000+1000是只有两段,1+1+1+1有4段,由于bfs返回的经过边数最少的解,这里会返回总长度2000的那个解,显然不是距离最短的路径。此时我们就应该采用Dijkstra最短路算法解决加权路径的最短路了。


应用:

1、寻找非加权图(或者所有边权重相同)中任两点的最短路径。

2、寻找其中一个连通分支中的所有节点。(扩散性)

3、bfs染色法判断是否为二分图。


一些思考:

1、当中为什么要用queue来存点而不是stack呢?

我们来举个例子,目前我们的队列中有一个起始节点。第一轮扩展之后,队列里有起始点的上、右、下、左四个点,现在我们就要把这四个点进行一下一轮轮扩展。也就是下一个队列里面的节点应该是“上”的四个方向、“右”的四个方向、“下”的四个方向、“左”的四个方向的点(已经有“已走过”标记的点当然的就不加了)。如果我们用的是stack,对‘上’点,我们把它爆掉,然后由stack的性质把它的四个方向的点丢到队列的头。照理说我们取完“上”点扩展之后之后,应该取的是剩余的右、下、左点来继续完成这一轮队列的扩展,可是stack把“上”节点的四个扩展点扔到了右、下、左三个节点的前面了。根据bfs队列区点规则,每一次取的都是队首那个点。这样就下一个取出来进行扩展的就是一阶点“上”节点的四个二阶扩展点了(假设初始队列里的元素是一阶,扩展一次增加一阶),然后队头就变成了三阶点。根据stack,再下一步就是把三阶取出来变四阶,原本第一次扩展就应该加入的那些一阶点一直被堵在厕所哭,明显是错的。如果是queue的话,每次把高一阶的扩展点扔到后面,这样扩展就是队列里的点按顺序扩展挨个加一阶,一阶一阶刷下去。


2、bfs不用担心队列里一直有点,空不了,因为所有的点慢慢扩展会跑到图外去,在边界限制条件那里就被刷掉了。所以除了那种因为题意不能标记已走过点的题(见下文应用规则2)需要考虑队列里的点重复走死循环,其他用了标记的都不用担心这个问题。


3、bfs能不能记录路径呢?

当然可以,我们可以把走的每一个点的父节点记录下来,最后挨着回溯回去就可以了。


使用规则

1、只要一看到要找最短的路就就在bfs和最短路 二者中选其一。无权用bfs,有权用最短路。

2、如果第二次回到刚才已走过的点的时候有状态参数变化(比如走的时候背了个定时炸弹,走一步计时器就少一步),那么就不能标记。

    原文作者:BFS
    原文地址: https://blog.csdn.net/geecky/article/details/51862444
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞