zoukankan      html  css  js  c++  java
  • 队列和 BFS —— 栈和 DFS

    队列和 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。但这不是从 AG 的最短路径。

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

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

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

    总结:

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

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

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

    欢迎关注微.信公.众号:爱写Bug
    在这里插入图片描述

  • 相关阅读:
    spring读取properties配置文件
    WxCpMessageRouter SpringContextHolder
    Maven和Spring mvc下的页面的跳转与取值
    struts2里UI页面标签
    Struts2中集合收集表单数据
    struts2的集合标签
    Struts2的通用标签(数据标签和控制标签)
    多个XML文件的包含与继承关系
    当出现异常时跳转到指定页面
    关于Struts2的动态URL和动态参数
  • 原文地址:https://www.cnblogs.com/zhangzhe532/p/11358839.html
Copyright © 2011-2022 走看看