在STL中扩充/索引priority_queue

时间:2013-11-14 23:24:05

标签: c++ c++11 stl

我在我的图形应用程序中使用STL priority_queue作为数据结构。您可以安全地将其视为Prim的生成树算法的高级版本。 在算法中,我希望有效地在优先级队列(而不仅仅是最小节点)中找到一个节点。[这是必需的,因为节点的成本可能会改变,需要在priority_queue中修复] 我所要做的就是扩充priority_queue并根据我的节点密钥对其进行索引。我发现在STL中无法做到这一点。任何人都可以更好地了解如何在STL中做到这一点?

1 个答案:

答案 0 :(得分:2)

std::priority_queue<T>不支持有效查找节点:它使用d-ary heap,通常使用d == 2。此表示不会保留节点。如果您真的想要使用Prim算法的std::priority_queue<T>,唯一的方法是只添加当前最短距离的节点,并可能多次添加每个节点。这会将大小变为O(E)而不是O(N),但是,对于具有许多边缘的图形,它将导致更高的复杂度。

您可以使用类似std::map<...>的内容,但实际上遇到的问题几乎相同:您可以找到下一个节点以便有效提取,也可以找到要高效更新的节点。

“正确”的方法是使用基于节点的优先级队列,例如Fibanocci-heap:由于节点保持不变,您可以在插入节点时从堆中获取句柄并有效地更新距离通过句柄的节点使用堆树集中的少数顶级节点可以有效访问最近的节点。 Fibonacci堆的基本堆操作(push()top()pop())的整体性能比d-ary堆慢,但单个节点的有效更新使它们的使用变得有价值。我似乎记得Prim的算法实际上需要Fibonacci-sheaps来实现严格的复杂性限制。

我知道在Boost有一个斐波那契堆的实现。 Fibonacci堆的有效实现并非完全无足轻重,但它们比仅仅具有理论兴趣更有效。