树的搜索问题1(深度优先、广度优先,爬山法和best-first)

前言

我们在解决问题中经常使用到的数据结构一定少不了树,在数据结构这一大块中,我们对每一个结构都会讲各种形形色色的操作,比如栈的压栈出栈,树的各种遍历,但其实数据结构最重要的操作其实是搜索。如果我们不知道链表的搜索,如何插入删除?不知道图的搜索,如何寻找最小生成树?

虽然我们讲的是树的搜索,但是本篇文章探讨的问题并非是树,而是将问题转化为树结构来处理。

树的几种常见搜索方式

我们先给出几种常用的例子吧。

  1. 布尔表达式,给一组布尔变量和一个用这些变量组成的布尔表达式,需要寻找一种赋值方式使表达式为真在这里插入图片描述

  2. 8-puzzle问题,给一个九宫格,需要进行排序在这里插入图片描述

  3. 有n个结点的连通图G=(V,E),V为点集,E为边集,寻找哈密顿环。
    哈密顿环是沿着边遍历每一个结点有且仅有一次最后回到起点的环

上述的三个问题,很明显都是能将问题转换成一棵树结构的,第二个就是每次移动一格来形成树;第三个哈密顿环就不用说了,很明显的每一次选择一个顶点,标准树结构。
而且上述问题都是遍历树寻找正确答案的那种,所以我们先解决这几个问题。

接下来给出几个常用的树搜索策略:

  • 暴力搜索
  • 深度优先
  • 广度优先

这几个其实都不常用,嗯就是这样,尤其第一个。
这里提到的原因主要是后面的其实还是会用到这些基本解决办法

深度优先
说白了就是在搜索的时候,我们先从一条线走到叶子节点,然后回到上一个分支处,从另一条分支走,不断重复直到最后我们找到目标节点或者遍历完整棵树
在这里插入图片描述
比如这样的一棵树,我们深度优先的方式就是ABD(回溯到A)CG(回溯到C)EF

因为需要回溯,所以我们采取的数据结构为

  1. 首先将根节点压栈,
  2. 判断栈顶元素是否为目标结点,不是继就续
  3. 将栈顶弹出,将被弹出元素的所有孩子结点压栈(按照从右到左的顺序,因为我们要保证先走左子树)
  4. 当S为空,说明没找到,否则继续操作2

广度优先
首先,广度优先和深度优先相似,但是我们这次采取的方法是先遍历行
从顶点开始,先遍历所有的子节点,然后遍历第一个孩子结点的孩子结点,然后是第二个孩子的……
在这里插入图片描述
还是这棵树,这次我们广度优先的结果是:ABCD(找到第二个孩子C)GEF

因为也需要回溯,我们还是找一个结构存起来,这次我们采取的是队列

  1. 首先将根节点入队列
  2. 如果队列首元素是目标节点,结束程序
  3. 否则将队首元素出队,将其所有孩子结点入队
  4. 如果队列为空,说明没有找到,否则重复操作2

爬山法

在深度优先和广度优先中,我们每一个根节点都会遇到很多个可拓展对象,那么哪一个先进行就是一个问题,
但我们还学过贪心啊(点击查看博客),我们能否将两者合并?

爬山法就是这样的产物,是由贪心算法深度优先算法相结合的产物。
同深度优先,爬山法也需要使用

  1. 将根节点压栈
  2. 如果栈顶元素就是我们的目标节点,结束
  3. 将栈顶元素出栈,同时将出栈的元素按照一定的顺序压栈
  4. 如果栈空,说明没找到;否则继续操作2

就是将我们深度优先的压栈方式改了一下么,那么这一定的顺序是什么呢?
比如在8-puzzle问题中,我们需要将8个方块归位,那么我们就可以定义一个测度,这里的测度是放置错误的方块的个数,毕竟当前正确的方块越多,按理来说就应该更接近问题的正确答案。
在这里插入图片描述
然后,我们来看一下贪心部分,很明显,他不能保证每一次都是最好的……
接下来,就需要进一步优化了。
(虽然不能保证最好,但是在有些情况下用着也还行,kmp还牛皮了,但是我们暴力匹配一下也没啥,工程上也总是直接贪心,不怎么考虑正确性)

best-first

有没有一种方法,既能快速又能产生最短结果的方法?
之前是深度优先的同时,就直接选取了贪心出来的当前最优解,那么我们可以效仿广度优先,将当前所有的可能比较一下,而不是将目光限定在当前的一条分支的选择上。

比如上面的8-puzz问题截图,在爬山法选定最左边的3之后,我们的目光就停在2和4上了,
而我们的bf算法,则是将2、4和上一步留下的344都一起考虑了。

这次我们的存储结构再次更换,使用的是
(如果对堆不够清楚,这是之前关于堆的博客

  1. 将根节点存入堆中
  2. 如果堆的根节点是目标节点,结束程序
  3. 否则将根节点删除,将根节点的孩子节点加入堆中
  4. 如果堆为空,说明没找到,否则就继续操作2

在这种方法中,我们的贪心策略就是成立的,因为是全局选择。

总结

我们在这篇博客中讲解了深度优先、广度优先,虽然只是简单提了一下,
然后延申出了基于深度优先和贪心的爬山法,
还有深度优先、广度优先和贪心的best-first算法。
这些方法不但在上述问题中会遇到,而且在我们的下一篇博客也会提到关于最值问题的解决办法。
(提示一下,这篇博客主要是讲从树结构中选择正确的答案,但在最值问题中我们不知道最佳答案,这时就需要其他的算法了。)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值