BFS 宽度优先搜索——初学

来源:互联网 发布:1024程序员节 编辑:程序博客网 时间:2024/05/17 02:25

        初学BFS,做了几道题后对BFS有了一点简单的认识,稍微整理一下思路,我想这会有利于以后的学习,顺便整理一点资料或许会有利于共同学习;

                                                             

           宽度优先搜索算法(又称广度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和宽度优先搜索类似的思想。

          已知图G=(V,E)和一个源顶点s,宽度优先搜索以一种系统的方式探寻G的边,从而“发现”s所能到达的所有顶点,并计算s到所有这些顶点的距离(最少边数),该算法同时能生成一棵根为s且包括所有可达顶点的宽度优先树。对从s可达的任意顶点v,宽度优先树中从s到v的路径对应于图G中从s到v的最短路径,即包含最小边数的路径。该算法对有向图和无向图同样适用。

之所以称之为宽度优先算法,是因为算法自始至终一直通过已找到和末找到顶点之间的边界向外扩展,就是说,算法首先搜索和s距离为k的所有顶点,然后再去搜索和S距离为k+l的其他顶点。

                                                                                                                                                           -----《算法导论》

 

 BFS解题基本思想
  (1)建立一个空的状态队列Q;
  (2)把初始状态begin存入队列Q;
  (3)若队列状态是目标状态,则搜索成功,运行中止;若搜索已经达到边界或其他极限,则搜索失败,运行结束,无解;如果按某种原则取一个满足条件的的节点,并将其置于Q的最后,继续扩展其他节点,若扩展失败,即没有新状态产生,则将Q中第一个状态从Q中除去,执行下步;
  (4)若SS成为空队列,则搜索失败,算法运行结束,没有解。否则转执行步骤(3)。


BFS的最终可能的结果

两种结果:1.到目标结点,2。扩展完所有结点而没有找到目标结点。
如果目标结点存在于解答树的有限层上,广度优先搜索算法一定能保证找到最优路径,因此广度优先搜索算法特别适用于求最优解的问题。如果问题需要给出解的路径,则要保存每个扩展节点的路径。

 

可用BFS解的的题目特征:

1)问题规模较小;
2)可以从一个状态按照问题给定的条件,转变为另外的一个或几个状态;
3)可以判断一个状态的合法性,并且有明确的一个或多个目标状态。
4)需要解决的问题是:根据给定的初始状态找出目标状态,或根据给定的初始状态和结束状态,找出一条从初始状态到结束状态的路径。


BFS具体实现:

     由于宽度优先搜索是层序遍历,所以假如B,C是A的节点的话,那么A一定先于B,C被访问,同理B,C一定先于B,C的子结点被访问,于是很容易想到可以用队列来实现,具体框架

            定义一个队列;

            起始点入队;

                while(队列不空){

            队头结点出队;

            若它是所求的目标状态,跳出循环;

            否则,将它扩展出的子结点,全都入队;

                }

            若循环中找到目标,输出结果;

            否则输出无解;

由此可以看出,它的基本过程就是:每次队头元素出队时,扩展其全部的子结点,并用队列记录下来。 搜索过程没有回溯,是一种牺牲空间换取时间的方法。

以一道经典的题目来说明BFS的具体实现过程:(UVA 439 - Knight Moves)

见另一篇日志:http://lingyunjinzhu.blog.163.com/blog/static/1810152232011728113035893/

 

另外附一些BFS题目:

             POJ : 1011  1915  2243  1979    2225         2251     2312   3126     3278

             HDU:   1241  1242  1253 1372