在我正在学习的一门算法课程中,据说深度优先搜索(DFS)比广度优先搜索(BFS)更节省空间。
为什么呢?
虽然它们基本上都在做相同的事情,但在DFS中,我们正在堆叠当前节点的后续节点,而在BFS中,我们正在将后续节点排队。
在DFS中,使用的空间是O(h),其中h是树的高度。
在BFS中,使用的空间是O(w),其中w是树的“宽度”。
在典型的二叉树(即随机二叉树)中,w=ω(n)和h=O(sqrt(n))。
在平衡树中,w=Omega(n)和h=O(log n)。
在DFS中,完全平衡树上的线性深度O(log(n))
只需要空间,而BFS(宽度优先搜索)需要O(n)
(树的最宽部分是二叉树中n/2个节点的最低深度)。
例子:
1
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
2 2
/ \ / \
/ \ / \
/ \ / \
/ \ / \
3 3 3 3
/ \ / \ / \ / \
/ \ / \ / \ / \
4 4 4 4 4 4 4 4
/ \ / \ / \ / \ / \ / \ / \ / \
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
DFS需要空间:4
BFS需要在最后第二行空间8
如果分支因子越高,情况就会变得更糟
您的困惑源于这样一个事实,即您显然认为DFS算法可以通过用后进先出堆栈替换FIFO队列从BFS算法获得。
这是一个普遍的误解——这根本不是真的。经典的DFS算法不能通过用堆栈替换BFS队列来获得。这些算法之间的差异要显著得多。
如果您采用BFS算法,并简单地用后进先出堆栈替换FIFO队列,您将获得可以称为伪DFS算法的东西。这种伪DFS算法确实可以正确地再现DFS顶点前向遍历序列,但它不具有DFS空间效率,并且不支持DFS后向遍历(回溯)。
同时,通过这种简单的队列到堆栈替换,无法从BFS获得真正的经典DFS。经典的DFS是一种完全不同的算法,具有显著不同的核心结构。True DFS是一种真正的递归算法,它使用堆栈进行回溯,而不是存储顶点发现“前端”(如BFS中的情况)。最直接的结果是,在DFS算法中,最大堆栈深度等于DFS遍历中距原点顶点的最大距离。在BFS算法中(如前面提到的伪DFS),最大队列大小等于最大顶点发现前沿的宽度。
说明DFS和BFS(以及伪DFS)之间内存消耗峰值差异的最突出和最极端的例子是星图:一个由大量外围顶点包围的单个中心顶点(例如,1000
)外围顶点通过边缘连接到中心顶点。如果在此图上使用中心顶点作为原点运行BFS,队列大小将立即跳转到1000
。如果使用伪DFS(即简单地用堆栈替换队列),显然会发生同样的事情。但是经典的DFS算法只需要1
(!)遍历整个图表。看出区别了吗?1000
对1
。这就是DFS更好的空间效率的含义。
基本上,阅读任何一本关于算法的书,找到经典DFS的描述,看看它是如何工作的。您会注意到,BFS和DFS之间的区别远远大于队列与堆栈之间的区别。
另外,还应该说,我们可以构建一个图的示例,该图在BFS下具有较小的峰值内存消耗。因此,关于DFS更好的空间效率的声明应该被视为可以“平均”应用于某些隐含的“nice”图类。
本文向大家介绍什么是深度优先搜索?相关面试题,主要包含被问及什么是深度优先搜索?时的应答技巧和注意事项,需要的朋友参考一下 如算法名称那样,深度优先搜索所遵循的搜索策略是尽可能“深”地搜索树。它的基本思想是:为了求得问题的解,先选择某一种可能情况向前(子结点)探索,在探索过程中,一旦发现原来的选择不符合要求,就回溯至父亲结点重新选择另一结点,继续向前探索,如此反复进行,直至求得最优解。深度优先搜索
算法相对较新,所以如果我遗漏了一些显而易见的东西,请原谅! 我知道深度优先搜索的空间复杂度通常表示为O(h),其中h是树的高度,而广度优先搜索的复杂度是O(n),其中n是树中节点的数量。 我理解解释(例如在这个答案中https://stackoverflow.com/a/9844323/10083571)也就是说,在BFS中最坏的情况下,所有节点都在一个级别上,这意味着我们必须在遍历它们之前将所有
我有一个无向连通图。我使用邻接矩阵实现了它,它是一个2维数组。 据我所知,DFS在兄弟节点之前访问子节点。BFS先于孩子探望兄弟姐妹。 这两个我是这样实现的: 如果让我执行一个从D到E的DFS,是D、C、a、E还是D、E。我以为DFS和BFS必须访问每个节点,在这种情况下B不能访问。我不知道我应该如何改变我目前的方法来满足这些要求。
主要内容:深度优先搜索(简称“深搜”或DFS),广度优先搜索,总结前边介绍了有关图的 4 种存储方式,本节介绍如何对存储的图中的顶点进行遍历。常用的遍历方式有两种: 深度优先搜索和 广度优先搜索。 深度优先搜索(简称“深搜”或DFS) 图 1 无向图 深度优先搜索的过程类似于树的先序遍历,首先从例子中体会深度优先搜索。例如图 1 是一个无向图,采用深度优先算法遍历这个图的过程为: 首先任意找一个未被遍历过的顶点,例如从 V1 开始,由于 V1 率先访问过了,所以
本文向大家介绍深度优先搜索,包括了深度优先搜索的使用技巧和注意事项,需要的朋友参考一下 图遍历是按某种系统顺序访问图的所有顶点的问题。遍历图主要有两种方法。 广度优先搜索 深度优先搜索 深度优先搜索(DFS)算法从顶点v开始,然后遍历到之前未访问过的相邻顶点(例如x),并将其标记为“已访问”,然后继续处理x的相邻顶点,依此类推。 如果在任何一个顶点上遇到所有相邻顶点都被访问过,则它将回溯直到找到具
本文向大家介绍什么是广度优先搜索?相关面试题,主要包含被问及什么是广度优先搜索?时的应答技巧和注意事项,需要的朋友参考一下 类似树的按层遍历,其过程为:首先访问初始点Vi,并将其标记为已访问过,接着访问Vi的所有未被访问过可到达的邻接点Vi1、Vi2……Vit,并均标记为已访问过,然后再按照Vi1、Vi2……Vit的次序,访问每一个顶点的所有未被访问过的邻接点,并均标记为已访问过,依此类推,直到图