【问题标题】:Dijkstra's algorithm - how could a priority queue or min-heap be used?Dijkstra 的算法 - 如何使用优先级队列或最小堆?
【发布时间】:2014-02-21 11:22:10
【问题描述】:

我一直在努力实现 Dijkstra 的算法;更具体地说,具有优先级队列的部分。将顶点添加到数据结构中并使用迭代器遍历所有顶点并找到最小距离;这很容易,但 n 次。

我想要的是:

  • 能够将顶点插入到数据结构中
  • 提取(返回并移除)距离dist[v]最小的顶点v

我相信,为了让 Dijkstra 算法正常工作,您应该能够在恒定时间内插入顶点并在 log(n) 时间内提取它们;并且有人建议我可以使用优先级队列和最小堆,但对我来说,保持队列或最小堆有序似乎并不现实,因为距离会不断修改。

那么我应该如何声明和使用优先级队列、最小堆或其他数据结构来做到这一点?

【问题讨论】:

    标签: c++ algorithm queue priority-queue dijkstra


    【解决方案1】:

    您可以使用一对将节点与值一起存储(第一个元素应该是值,以便优先级队列与该值进行比较)。维护一个布尔数组visit [ ],您将在其中指出您是否访问过某个节点(最初全部为假)。

    每次你取优先队列的最前面的元素时,检查你是否访问过这个节点,即检查是否visit[pq.front().second] == false。检查其所有相邻边并添加从此路径到达的节点。如果它是真的那么你应该忽略它,因为你已经用更少的长度访问了它。您不会添加超过 E 条边,因此时间复杂度保持不变。

    您可以在此链接http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=standardTemplateLibrary2#priority 中了解有关此方法的更多信息。

    【讨论】:

      【解决方案2】:

      你在这里基本上有三个选择:

      1. 使用允许您在O(logN) 中提取任意数字的树或其他一些 DS。堆不能提供这种行为。
      2. 维护一个映射map:V->Node Reference的附加DS(可能是基于哈希的) - 这将允许您在堆中有效地找到所需的节点,并在O(logN)中删除您知道其位置的节点是可行的堆(问题在于发现...)
      3. “仍然插入”,忽略堆已包含此节点的事实。这将导致您拥有更大的堆,大小为O(n^2) 最坏情况(边数),但请记住log(N^2)=2log(N)O(logN)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-23
        • 1970-01-01
        • 1970-01-01
        • 2020-08-09
        • 2012-09-10
        • 1970-01-01
        • 2019-10-29
        相关资源
        最近更新 更多