让我们说我已经使用PriorityQueue实现了dijkstras,以便在未访问的节点上进行添加和删除需要O(log n)。
PQ最多包含E个节点,因此将其清空可以得到O(E)。当PQ不为空时,我们采取最佳节点并将其删除,如果未访问,请访问并遍历其所有邻居(可能将其添加到PQ中)。
我不了解的地方:如何在E个项目最差的情况下遍历所有邻居(在最差的V下)不具有O(E * V)的时间复杂性。我已经看到了太多的解释,以至于我们只应该看一下操作并观察它们将执行多少次并从中得出结论。我看不到如何忽略我们正在遍历V个邻居的事实,n个项目的空for循环仍然是O(n)?
对我来说,最终的复杂度似乎是O(V + E * V log E)而不是O(V + V log E)。我的意思是有很多差异,但要点是我缺少一些琐碎的:P
答案 0 :(得分:0)
您似乎混淆了的术语的第一点。 E
不是项目数,而是顶点之间的边数。 V
是顶点的数量,(取决于上下文)很可能是项目的数量。
接下来,“此顶点是该顶点的邻居”意味着它们之间存在边。每个边缘贡献2个邻居关系。 (每个方向一个。)因此,2 E
是总共可以存在的邻居关系的数量。
您的直觉是,V
个节点中的每个节点最多可以拥有V-1
个邻居,总共V2-V
个邻居关系是正确的-但您可以告诉您与最差的邻居有多近从边缘的数量来看。
因此,我们完成了以下潜在工作:
for each of E edges:
for each vertex on that edge:
O(1) work to check whether it was processed yet
(processing the vertex if needed accounted for separately)
for each of V vertices:
O(log(V)) to add to the priority queue
O(log(V)) to remove from the priority queue
(processing its edges accounted for separately
第一个块是O(E)
。第二个块是O(V log(V))
。总数为O(E + V log(V))
。
希望这种解释可以弄清为什么如此复杂。