来自Wikipedia:O(|E| + |V| log|V|)
来自Big O Cheat List:O((|V| + |E|) log |V|)
我认为E + V log V
和(E+V) log V
之间存在差异,不存在吗?
因为,如果维基百科的一个是正确的,那么它不应该只显示为O(|V| log |V|)
(因为我不理解的原因,删除|E|
)?)
Dijkstra与Fibonacci-Heap的大O是什么?
答案 0 :(得分:18)
Dijkstra最短路径算法的复杂性是:
O(|E| |decrease-key(Q)| + |V| |extract-min(Q)|)
其中Q
是按当前距离估计排序顶点的最小优先级队列。
对于Fibonacci堆和二进制堆,此队列上的extract-min操作的复杂性为O(log |V|)
。这解释了总和中常见的|V| log |V|
部分。对于使用未排序数组实现的队列,extract-min操作的复杂度为O(|V|)
(必须遍历整个队列),并且这部分总和将为O(|V|^2)
。
在和的剩余部分(具有边缘因子| E |的部分)中,O(1)
v。 O(log |V|)
的区别恰恰来自于分别使用Fibonacci堆而不是二进制堆。每个边缘可能发生的减少键操作恰好具有这种复杂性。因此,总和的剩余部分最终对于Fibonacci堆具有复杂度O(|E|)
而对于二进制堆最终具有O(|E| log |V|)
。
对于使用未排序数组实现的队列,reduce-key操作将具有恒定时间复杂度(队列直接存储由顶点索引的键),因此该部分的总和将为O(|E|)
,这是还O(|V|^2)
。
总结:
O(|E| + |V| log |V|)
O((|E| + |V|) log |V|)
O(|V|^2)
因为在一般情况|E| = O(|V|^2)
中,如果不对所处理的图表进行进一步的假设,就不能进一步简化这些。
答案 1 :(得分:0)
Dijkstra是带有Fibonacci堆的O(| E | + | V | log | V |)和没有它的O((| V | + | E |)log | V |)。
两者都以某种方式纠正。 Big O Cheat List显示最常见的实现和Wiki最好的。
O(| E | + | V | log | V |)不在O(| V | log | V |)btw中。 E在O(| V | ^ 2)中,而不是O(| V | log | V |)。