所以希望这是一个简单的问题,但我似乎无法找到答案。
据称DFS的时间复杂度为O(|V|+|E|)
。现在我遇到问题,看看为什么它取决于边数。我见过的通常解释如下:
假设我们使用显式堆栈实现DFS(为简单起见)。假设我们有一个图表,其中每个节点都连接到所有其余节点。我们从某个节点开始,访问它然后将它的所有邻居推入堆栈。现在我们弹出下一个节点并将其所有邻居放入堆栈。我们重复,直到我们访问所有节点。
让我们假设在每次迭代中都没有访问发现自己位于堆栈顶部的节点(此图的最佳情况)。在这种情况下,我们访问了|V|
个移动中的所有节点,但是对于每个节点,我们在堆栈上推送了|V|-1
个节点,这意味着所有边都被推到堆栈上,复杂度为{{1 }}
一些笔记。我认为复杂性比这更复杂,所以这个证据只能看最坏情况图的最佳情况。我还假设O(|E|)
总是大于|E|
。事实上,我假设它是|V|
。这意味着O(|V|^2)
和O(|V|+|E|)
对我来说意味着同样的事情。
好的,现在这是我的交易。如果我们不使用显式堆栈怎么办?
这里的爆炸是因为我们不断堆积永远不会被处理的无用节点。如果我们只是递归怎么办?优点是我们可以在每次递归调用之前检查是否已完成。
由于没有明确的堆栈,我仍然只访问我以前从未见过的节点,我不知道如何超越O(|E|)
的复杂性。
答案 0 :(得分:2)
这里的爆炸是因为我们不断堆积永远不会被处理的无用节点。如果我们只是递归怎么办?优点是我们可以检查在每次递归调用之前我们是否已完成。
该检查仍然有助于运行时间。对于您访问的每个节点,您需要查看仍需要访问哪些邻居,这意味着要检查每个相邻边缘。