宽度优先搜索

又有的时候,我们还会碰到这样一些貌似可以用深搜解决,但又有点茫然打不出深搜程序的题:奇怪的电梯、倒牛奶、面积……这些问题,问的都是最怎么怎么样,但也是从一个起点出发往下走。怎么办?这时候我们就要用到一个新的算法。虽然也叫搜索,但它并没有回溯这个操作。它和深度优先搜索一样,有个昵称:广度优先搜索。当然了,它肯定有个正式名称,那就是

宽度优先搜索(BFS,简称宽搜)

那么,宽度优先搜索又是个什么东西?它和深度优先搜索又有什么区别?我会在这里一一介绍。


一、宽度优先搜索的思想

宽度优先搜索是从一个节点(位置)出发,拓展出所有它可以拓展出来的节点(位置)。接着,指针移到下一个位置,对这个位置继续进行拓展,然后指针再移到下一个位置,再继续拓展……直到找到答案为止。
它和深度优先搜索不同,深度优先搜索是“往死里走”,宽度优先搜索则是不紧不慢地,先拓展完一个再拓展另一个。


二、宽度优先搜索的基本用途

宽度优先搜索一般在“最值问题”中会大显身手,当然在总的方案问题中也占有一席之地(当深搜会爆栈时)。在图论问题中,它也经常用来遍历一个图;树的遍历,有时也会用来完成。


三、宽度优先搜索的写法

与深搜不同,宽搜一般用while循环来实现。宽度优先搜索其实相当于创建一个队列(或者说填充数组),要用两个指针i,j。i表示当前正在拓展的节点(位置),j表示这个数组的终点。
以下是宽度优先搜索的框架:

初始化data、i=0、j=1和标记(凡是搜索都离不开标记这个玩意儿,一定要记住!不然Runtime Error或者Time Limit Exceeded别怪我没说过!)
while(i<j)//即还有节点可以拓展
{
    i++;
    for(int s=1;s<=方向个数(或者说可以拓展的节点数量,譬如说假如是走迷宫,那么就有四个或者八个方向;如果是电梯上下,那么就有上和下两个方向);s++)
    if(满足条件且拓展的新节点没被访问过)
    {
        j++;
        拓展新节点;记录步数;标记;
        if(新节点==目标节点) printf步数,退出;(如果是求总的方案,则ans++}
}

为什么发现到目标节点了,所用步数就一定是最少的呢?
因为宽度搜索是一层一层的遍历,如果找到了一个目标节点,那么它一定是用最少步数找到的。
(高阶亿点的解释,把宽度优先搜索的结果列成一个图,就变成了一棵树,步数就是这个节点在这棵树的层数,而这个层数一定是离根节点(起点)最短的。)


四、使用宽搜的注意事项

  1. 记录每一个节点数据的打他data数组一定要开大,一定要保证装的下所有可能的状态(本人就有不少于5次因为data没开够而Runtime Error的前车之鉴)当你发现空间不够时,别心软,把它踢一边去(换一个新的算法)!
  2. 当你发现一道题可以用深搜也可以用宽搜(并且两者都是100%能拿100分)时,你就要量力而行了,自己擅长用哪个算法就用哪个算法(本人喜欢用深搜,你们的程序你们做主哈
  3. 宽度优先搜索的标记一定要深思熟虑之后再定,要仔细想清楚标记表示什么意思(一般一个数据有几个量就用几维,但是有些情况量太多,这时候要想清楚用什么做标记)。

总而言之,宽度优先搜索虽然比起深搜来小众那么一点点,但它还是很常用的。大家一定要好好学好BFS哟!

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值