递归DFS的复杂性

时间:2016-01-15 17:49:59

标签: algorithm recursion time-complexity depth-first-search

所以希望这是一个简单的问题,但我似乎无法找到答案。 据称DFS的时间复杂度为O(|V|+|E|)。现在我遇到问题,看看为什么它取决于边数。我见过的通常解释如下:

假设我们使用显式堆栈实现DFS(为简单起见)。假设我们有一个图表,其中每个节点都连接到所有其余节点。我们从某个节点开始,访问它然后将它的所有邻居推入堆栈。现在我们弹出下一个节点并将其所有邻居放入堆栈。我们重复,直到我们访问所有节点。

让我们假设在每次迭代中都没有访问发现自己位于堆栈顶部的节点(此图的最佳情况)。在这种情况下,我们访问了|V|个移动中的所有节点,但是对于每个节点,我们在堆栈上推送了|V|-1个节点,这意味着所有边都被推到堆栈上,复杂度为{{1 }}

一些笔记。我认为复杂性比这更复杂,所以这个证据只能看最坏情况图的最佳情况。我还假设O(|E|)总是大于|E|。事实上,我假设它是|V|。这意味着O(|V|^2)O(|V|+|E|)对我来说意味着同样的事情。

好的,现在这是我的交易。如果我们不使用显式堆栈怎么办?

这里的爆炸是因为我们不断堆积永远不会被处理的无用节点。如果我们只是递归怎么办?优点是我们可以在每次递归调用之前检查是否已完成。

由于没有明确的堆栈,我仍然只访问我以前从未见过的节点,我不知道如何超越O(|E|)的复杂性。

1 个答案:

答案 0 :(得分:2)

  

这里的爆炸是因为我们不断堆积永远不会被处理的无用节点。如果我们只是递归怎么办?优点是我们可以检查在每次递归调用之前我们是否已完成

该检查仍然有助于运行时间。对于您访问的每个节点,您需要查看仍需要访问哪些邻居,这意味着要检查每个相邻边缘。