第五章:广度优先搜索

在广度优先搜索算法中,解答树上结点的扩展是按它们在树中的层次进行的。首先生成第一层结点,同时检查目标结点是否在所生成的结点中,如果不在,则将所有的第一层结点逐一扩展,得到第二层结点,并检查第二层结点是否包含目标结点,……,对层次为n+1的任一结点进行扩展之前,必须先考虑层次完层次为n的结点的每种可能的状态。因此,对于同一层结点来说,求解问题的价值是相同的,可以按任意顺序来扩展它们。通常采用的原则是先生成的结点先扩展。

为了便于进行搜索,要设置一个表存储所有的结点。由于在广度优先搜索算法中,要满足先生成的结点先扩展的原则,所以存储结点的表一般采用队列这种数据结构。

广度优先搜索算法的搜索步骤一般是:

(1)从队列头取出一个结点,检查它按照扩展规则是否能够扩展,如果能则产生一个新结点。

(2)检查新生成的结点,看它是否已在队列中存在,如果新结点已经在队列中出现过,就放弃这个结点,然后回到第(1)步。否则,如果新结点未曾在队列中出现过,则将它加入到队列尾。

(3)检查新结点是否目标结点。如果新结点是目标结点,则搜索成功,程序结束;若新结点不是目标结点,则回到第(1)步,再从队列头取出结点进行扩展。

最终可能产生两种结果:找到目标结点,或扩展完所有结点而没有找到目标结点。

如果目标结点存在于解答树的有限层上,广度优先搜索算法一定能保证找到一条通向它的最佳路径,因此广度优先搜索算法特别适用于只需求出最优解的问题。当问题需要给出解的路径,则要保存每个结点的来源,也就是它是从哪一个节点扩展来的。

对于广度优先搜索算法来说,问题不同则状态结点的结构和结点扩展规则是不同的,但搜索的策略是相同的。

对于不同的问题,用广度优先搜索法的算法基本上都是一样的。但表示问题状态的结点数据结构、新结点是否为目标结点和是否为重复结点的判断等方面则有所不同。对具体的问题需要进行具体分析,这些函数要根据具体问题进行编写。

可能对于上面的讲解,同学们还不是很了解什么是广度优先搜索,下面我们通过一个例子再来聊一聊什么是广度优先搜索。假设你自己经营了一家巧克力工厂,你需要找到巧克力销售商,这样你的巧克力才能卖出去。因此,你首先开始在你认识的朋友里面寻找,有没有巧克力销售商。如下图所示,你一共有三个好朋友,分别是马小云、刘小东和马小腾。

一开始的的查找很简单,你只需要创建一个朋友们的名单。然后依次检查名单中的每一个人,看看他是不是巧克力销售商。

首先,你开始查找你的朋友马小云,如果他是巧克力销售商,那么大功告成,查找也就结束了,如果他不是的话继续查找第二个朋友刘小东,同样如果他是巧克力销售商,那么大功告成,查找也就结束了,如果他不是的话继续查找第三个朋友马小腾,如果他是巧克力销售商,那么大功告成,查找也就结束了,如果他不是的话就表示你的朋友里面没有巧克力销售商。那接下来怎么办呢?很显然,接下来你就需要在查找你朋友的朋友有没有巧克力销售商了(是不是有点无脑枚举的意思?)。

同样,你需要首先把朋友的朋友的名单加入列表中,然后再一个个查找他们是否为巧克力销售商。这样一来,你不仅在朋友中查找,还在朋友的朋友中查找。别忘了,你的目标是在你的人际关系网中找到一位巧克力销售商。因此,如果马小腾不是巧克力销售商,就将其朋友也加入到名单中。这意味着你将在她的朋友、朋友的朋友等中查找。使用这种算法将搜遍你的整个人际关系网,直到找到巧克力销售商。这就是广度优先搜索算法。

广度优先搜索一般可以回答两类问题:

第一类问题:从节点A出发,有前往节点B的路径吗?(在你的人际关系网中,有巧克力销售商吗?)
第二类问题:从节点A出发,前往节点B的哪条路径最短?(哪个巧克力销售商与你的关系最近?)
刚才你看到了如何回答第一类问题,下面来尝试回答第二类问题——谁是关系最近的巧克力销售商。例如,朋友是一度关系,朋友的朋友是二度关系。

在你看来,一度关系胜过二度关系,二度关系胜过三度关系,以此类推。因此,你应先在一度关系中搜索,确定其中没有巧克力销售商后,才在二度关系中搜索。广度优先搜索就是这样做的!在广度优先搜索的执行过程中,搜索范围从起点开始逐渐向外延伸,即先检查一度关系,再检查二度关系。顺便问一句:将先检查刘小东还是雷小军呢?刘小东是一度关系,而雷小军是二度关系,因此将先检查刘小东,后检查雷小军。你也可以这样看,一度关系在二度关系之前加入查找名单。

你按顺序依次检查名单中的每个人,看看他是否是巧克力销售商。这将先在一度关系中查找,再在二度关系中查找,因此找到的是关系最近的巧克力销售商。广度优先搜索不仅查找从A到B的路径,而且找到的是最短的路径(貌似这里又有一点贪心的感觉了)。

注意,只有按添加顺序查找时,才能实现这样的目的。换句话说,如果马小云先于雷小军加入名单,就需要先检查马小云,再检查雷小军。如果马小云和雷小军都是巧克力销售商,而你先检查雷小军再检查马小云,结果将如何呢?找到的巧克力销售商并非是与你关系最近的,因为雷小军是你朋友的朋友,而马小云是你的朋友。因此,你需要按添加顺序进行检查。有一个可实现这种目的的数据结构,那就是队列(queue),所以这也就是我们之前学习队列知识的原因所在。

例题1:寻宝(主题库2638)                          

小萱萱参加了一个“寻宝”游戏:在一排均匀排列的树上,被随机放置了一个“宝贝”,看谁能以最少的时间找到这个“宝贝”。每一个寻宝的人开始会站在第N(0≤N≤100000)棵树边,假设树有100000 棵,“宝贝”被放在第K(0≤K≤100000)棵树上,寻宝人有两种移动办法:步行和跳跃。假如寻宝人现在在第X棵树边,步行每秒可以从第X棵树向第X-1棵和第X+1棵树走去,跳跃可以让她在1秒内从第X棵树直接跳到第2*X棵树边(假如他有超能力完成跳跃,跳跃过.程中不能超过树的边界)。现在要求找到“宝贝”需要的最短时间。

输入格式:仅有两个整数N和K。

输出格式:最短时间

输入样例:5 17

输出样例:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值