Dijkstra算法中堆积优于二叉树的优点

时间:2013-09-10 09:52:01

标签: algorithm data-structures binary-search-tree priority-queue dijkstra

Dijkstra算法的一个标准实现使用堆来存储从起始节点S到所有未探测节点的距离。使用堆的理由是我们可以在O(log n)中有效地弹出与它的最小距离。但是,为了保持算法的不变性,还需要更新堆中的一些距离。这包括:

  • 从堆中弹出非min元素
  • 计算更新的距离
  • 将它们插回堆中

我知道如果知道堆中该元素的位置,可以在O(log n)中完成从堆中弹出非min元素。但是,我无法理解在Dijkstra算法的情况下如何知道这个位置。听起来像二元搜索树更合适。

更一般地说,我的理解是堆唯一能比平衡二叉搜索树做得更好的是访问(不删除)min元素。我的理解是否正确?

1 个答案:

答案 0 :(得分:4)

  

但是,在Dijkstra算法的情况下,我无法理解如何知道这个位置。

您需要一个额外的数组来跟踪元素所在堆中的位置,或者堆元素中的额外数据成员。这必须在每次堆操作后更新。

  

堆唯一能比平衡二叉搜索树做得更好的是访问(不删除)min元素

除了根指针之外,甚至可以修改BST以保持指向min元素的指针,从而允许O(1)访问min(有效地分摊O(lg n )工作通过其他行动)。

堆在最坏情况复杂性方面的唯一优势是“堆化”算法,它通过在线性时间内就地重新组织其元素将数组转换为堆。对于Dijkstra来说,这没关系,因为无论如何它都会以O(lg n )的成本进行 n 堆操作。

然后,堆的真正原因是常量。正确实现的堆只是一个连续的元素数组,而BST是一个指针结构。即使在数组内部实现BST(如果从一开始就知道元素的数量就可以完成,如在Dijkstra中),指针占用更多内存,并且导航它们比使用的整数操作花费更多时间导航堆。