队列和 BFS:

广度优先搜索(BFS)的一个常见应用是找出从根结点到目标结点的最短路径。

示例


这里我们提供一个示例来说明如何使用 BFS 来找出根结点 A 和目标结点 G 之间的最短路径。

洞悉


观看上面的动画后,让我们回答以下问题:

1. 结点的处理顺序是什么?

在第一轮中,我们处理根结点。在第二轮中,我们处理根结点旁边的结点;在第三轮中,我们处理距根结点两步的结点;等等等等。

与树的层序遍历类似,越是接近根结点的结点将越早地遍历。

如果在第 k 轮中将结点 X 添加到队列中,则根结点与 X 之间的最短路径的长度恰好是 k。也就是说,第一次找到目标结点时,你已经处于最短路径中。

2. 队列的入队和出队顺序是什么?

如上面的动画所示,我们首先将根结点排入队列。然后在每一轮中,我们逐个处理已经在队列中的结点,并将所有邻居添加到队列中。值得注意的是,新添加的节点不会立即遍历,而是在下一轮中处理。

结点的处理顺序与它们添加到队列的顺序是完全相同的顺序,即先进先出(FIFO)。这就是我们在 BFS 中使用队列的原因。

栈和 DFS:

与 BFS 类似,深度优先搜索(DFS)也可用于查找从根结点到目标结点的路径。在本文中,我们提供了示例来解释 DFS 是如何工作的以及栈是如何逐步帮助 DFS 工作的。

示例


我们来看一个例子吧。我们希望通过 DFS 找出从根结点 A 到目标结点 G 的路径。

洞悉


观看上面的动画后,让我们回答以下问题:

1. 结点的处理顺序是什么?

在上面的例子中,我们从根结点 A 开始。首先,我们选择结点 B 的路径,并进行回溯,直到我们到达结点 E,我们无法更进一步深入。然后我们回溯到 A 并选择第二条路径到结点 C 。从 C 开始,我们尝试第一条路径到 E 但是 E 已被访问过。所以我们回到 C 并尝试从另一条路径到 F。最后,我们找到了 G。

总的来说,在我们到达最深的结点之后,我们只会回溯并尝试另一条路径。

因此,你在 DFS 中找到的第一条路径并不总是最短的路径。例如,在上面的例子中,我们成功找出了路径 A-> C-> F-> G 并停止了 DFS。但这不是从 A 到 G 的最短路径。

2. 栈的入栈和退栈顺序是什么?

如上面的动画所示,我们首先将根结点推入到栈中;然后我们尝试第一个邻居 B 并将结点 B 推入到栈中;等等等等。当我们到达最深的结点 E 时,我们需要回溯。当我们回溯时,我们将从栈中弹出最深的结点,这实际上是推入到栈中的最后一个结点。

结点的处理顺序是完全相反的顺序,就像它们被添加到栈中一样,它是后进先出(LIFO)。这就是我们在 DFS 中使用栈的原因。

总结:

显然BFS可以找到根节点到目标节点最短的路径,DFS可以最快的找到根节点到目标节点的路线,但却不一定是最短的。具体可参考维基百科:

BFS:https://zh.wikipedia.org/wiki/广度优先搜索

DFS:https://zh.wikipedia.org/wiki/深度优先搜索

欢迎关注微.信公.众号:爱写Bug

队列和 BFS —— 栈和 DFS的更多相关文章

  1. 栈及其DFS:B - Parentheses Balance

    解题心得及总结: 总结: 1.递推:又1推出n,数列中的基本到通项,最终目标得出通项公式. 递归:又n先压缩栈到1,再从函数的出口找到1,又1到n,再从n计算到1: 2.判断是否可以由递推或递推得出, ...

  2. 百炼3752:走迷宫--栈实现dfs

    3752:走迷宫 总时间限制:  1000ms 内存限制:  65536kB 描述 一个迷宫由R行C列格子组成,有的格子里有障碍物,不能走:有的格子是空地,可以走.给定一个迷宫,求从左上角走到右下角最 ...

  3. UVA10410-Tree Reconstruction(BFS序和DFS序的性质)

    Problem UVA10410-Tree Reconstruction Accept:708  Submit:4330 Time Limit: 3000 mSec Problem Descripti ...

  4. 遍历二叉树 - 基于队列的BFS

    之前学过利用递归实现BFS二叉树搜索(http://www.cnblogs.com/webor2006/p/7262773.html),这次学习利用队列(Queue)来实现,关于什么时BFS这里不多说 ...

  5. [LeetCode] Implement Stack using Queues 用队列来实现栈

    Implement the following operations of a stack using queues. push(x) -- Push element x onto stack. po ...

  6. UVALive 3486/zoj 2615 Cells(栈模拟dfs)

    这道题在LA是挂掉了,不过还好,zoj上也有这道题. 题意:好大一颗树,询问父子关系..考虑最坏的情况,30w层,2000w个点,询问100w次,貌似连dfs一遍都会TLE. 安心啦,这肯定是一道正常 ...

  7. 《剑指Offer》附加题_用两个队列实现一个栈_C++版

    在<剑指Offer>中,在栈和队列习题中,作者留下来一道题目供读者自己实现,即"用两个队列实现一个栈". 在计算机数据结构中,栈的特点是后进先出,即最后被压入(push ...

  8. Code POJ - 1780(栈模拟dfs)

    题意: 就是数位哈密顿回路 解析: 是就算了...尼玛还不能直接用dfs,得手动开栈模拟dfs emm...看了老大半天才看的一知半解 #include <iostream> #inclu ...

  9. 剑指offer编程题Java实现——面试题7相关题用两个队列实现一个栈

    剑指offer面试题7相关题目:用两个队列实现一个栈 解题思路:根据栈的先入后出和队列的先入先出的特点1.在push的时候,把元素向非空的队列内添加2.在pop的时候,把不为空的队列中的size()- ...

随机推荐

  1. Java 程序员应在2019年学习的10条面向对象(OOP)设计原则

    面向对象的设计原则 是 OOP 编程的核心,但是我看到大多数 Java 程序员都在追求诸如 Singleton 模式,Decorator 模式或 O​​bserver 模式之类的设计模式,而对学习面向 ...

  2. glibc编译安装

    glibc是gnu发布的libc库,即c运行库.glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc.glibc除了封装linux操作系统所提供的系统服务外,它本身也提供 ...

  3. 黄聪:PHP转换网址相对路径到绝对路径的一种方法

    相信很多程序(尤其是采集类的程序)都会有需要把网址的相对路径转换成绝对路径的需要,例如采集到某页面的HTML代码中包含资源文件经常会看到这样的文件名: <link rel="style ...

  4. 实现拖拽列表-微信小程序

    之前在网上搜索拖拽列表的实现时,发现了有好多的方法都是基于像素位置的计算实现的,这种方法要求列表元素的大小以及列表的位置有着非常严格的要求,修改和拓展起来非常的麻烦.于是我自己动手实现了一个基于页面元 ...

  5. CENTOS 7 升级内核版本(附带升级脚本)

    写在前面的话 对于系统而言,除非是那种安全性要求非常高的公司或者经常会有第三方安全机构对其漏洞扫描的才容易涉及到系统的内核升级,比如之前呆过一个公司,因为需要做三级等保的原因,就会涉及到系统扫描,这时 ...

  6. Elastic:如何在一个机器上同时模拟多个node

    Elastic:如何在一个机器上同时模拟多个node /bin/elasticsearch -E node.name=node1 -E cluster.name=my-application -E p ...

  7. hash算法原理及应用漫谈【加图版】

    原文:https://blog.csdn.net/Tencent_TEG/article/details/103021226 提到hash,相信大多数同学都不会陌生,之前很火现在也依旧很火的技术区块链 ...

  8. Python制作动态二维码只需要一行代码!炒鸡简单!

    分享一个比较有意思的项目,只需要一行Python代码就可以快捷方便生成普通二维码.艺术二维码(黑白/彩色)和动态GIF二维码. 用法比较简单,直接通过pip安装即可. pip3 install myq ...

  9. c++11 C++14 C++17

    Since C++11, WG21, the ISO designation for the C++ standard,  try to shipped the standard every 3 ye ...

  10. Java生鲜电商平台-你应该保留的一些学习态度与学习方法

    Java生鲜电商平台-你应该保留的一些学习态度与学习方法 说明:Java开源生鲜电商平台这一类学习课程系列已经初步接近了尾声,那么作为学习生鲜电商B2B2C电商的你,应该有一个什么样子的学习态度与学习 ...