至少有几个答案建议使用STL堆函数在Dijkstra算法中实现优先级队列:
Performance of Dijkstra's algorithm implementation
Implementing Dijkstra's Algorithm
如果STL不包含用于更新密钥的堆函数,那么在堆中重新排序顶点(line 19)的最佳方法是什么?
答案 0 :(得分:5)
你需要让顶点'冒泡'通过堆(根据需要与其父进行交换),直到它到达堆中的新位置。
改编自“算法入门”第2版的伪c ++。皮克。 140:
heap[pos] = new_weight;
while (pos > 0 && heap[parent(pos)] > heap[pos]) {
swap(heap[parent(pos)], heap[pos]);
pos = parent(pos);
}
其中int parent(int pos) { return (pos-1)/2; }
答案 1 :(得分:1)
我想有几种方法可以做到。
您可以手动执行筛选操作,并且基本上将值传递到堆顶部,弹出它,然后使用其新值将其推回堆上。
您可以更新该值并在堆上再次执行make_heap,假设make_heap设计为在堆是"几乎是堆"时有效。已经
您可以使用某个标记标记堆中的节点以指示它不再有效,然后在堆上使用新值推送新元素。然后,每次从堆中弹出一个元素时,都会检查该标志是否有效,并忽略任何无效元素。
否则,您可以使用具有更新功能的另一个堆实现。例如,Boost.Graph库在其详细信息(boost / graph / detail文件夹)中包含一个d_ary_heap.hpp标头,该标头实现了D-Ary Heap Indirect实现,该实现具有logN的更新功能。这用于Dijkstra和A *的BGL实现,您可以直接使用它,而不是实现自己的。