为什么图的邻接列表的BigO是(V + E)而不是(V ^ 2)?

时间:2016-08-04 13:54:20

标签: data-structures graph big-o adjacency-list space-complexity

如果我的想法错了,请纠正我。我认为BigO(V + E)= BigO(V ^ 2)。

以下是我的想法:
完整图中的边= = *(n-1)/ 2。

从E和V切换到n,因为我更容易这样思考。

E = n *(n-1)/ 2
V = n

BigO(V + E)=> BigO(n + n *(n-1)/ 2)=> BigO(n ^ 2)

将n切换回V。

=>戈(V ^ 2)

我错过了什么吗?为什么要使用BigO(V + E)?为什么不使用BigO(V ^ 2)?

3 个答案:

答案 0 :(得分:4)

邻接列表的内存使用量与节点数和边数之和成正比。这是因为每个节点具有离开它的边缘的相关列表,并且每个边缘最多出现两次(对于在无向图中触摸的每个节点一次,或对于有向图一次)。这意味着空间使用率为Θ(V + E)。

你在内存使用上给出了两个不同的渐近界限:O(V + E)和O(V 2 )。这两个边界都是正确的,但一个比另一个更紧。 O(V + E)界限更准确地表明有两个半独立量进入空间使用,节点数和边数,并且更精确。 O(V 2 )界限不太精确,但通过考虑E的最大可能值(以V为单位)给出总内存使用情况的最坏情况界限。换句话说,O(如果你试图精确地确定内存使用量,那么V + E)绑定会更有用,但是如果你担心最坏情况的内存,O(V 2 )的界限会更好的使用。

(快速说明:声明“邻接列表是O(V + E)”并不是一个有意义的句子。由于big-O量化了函数的增长率,它就像是说“邻接列表是95,201” “ - 它没有意义,因为你将一个对象与一个数字进行比较。但是,你可以说”邻接列表的空间使用是O(V + E)“,因为邻接列表的空间使用是一个实际的数字量。 )

答案 1 :(得分:0)

BigO用于根据输入大小估算您将使用多少<time, memory, whatever resource>

当您构建邻接列表时,您知道顶点数V和边数E。现在你想估计你需要多少内存。

O(V+E)可以解释为V > E ? O(V) : O(E)含义:它与max(V,E)线性复杂。

您为每个v创建一个列表,因此您可以使用O(V)内存。 您标记每个边缘,这使用O(E)内存。 O(V+E)就是这个意思。如果您认为复杂度为O(V^2),则意味着对于具有2*n顶点的空图表,您应该使用约。与4顶点的空图形相比,n时间更多。

在对复杂性进行一些研究时,您可以测试不同的方法:

  • 最坏的情况,
  • 平均情况,
  • 最好的情况。

如果您希望收到更多信息,请阅读有关该主题和评论的不同方法。

修改

根据正式定义,O(V+E)O(V^2)O(V^3)O(V^V^V)仍然是正确的。在BigO中,我们尝试找到效率最慢的函数,但仍然是BigO的复杂性。

答案 2 :(得分:0)

这两个陈述都是正确的。它们并不矛盾。

在任意图上,资源使用为O(V 2 )。但是在可能存在稀疏图的问题域中,资源使用是O(V + E)。这提供了更多信息。

邻接列表通常用于图表可能稀疏的问题域中。对于密集图,阵列通常是更好的解决方案。如果您正在考虑两种可能的算法来解决图形问题,则需要考虑您对图形的了解。学位是否受到限制?在这种情况下,邻接列表表示和相关算法可能是更好的解决方案。

复杂性分析不仅仅是一种理论游戏。这是一种组织您对实际编程问题的实际解决方案的思考的方法。