Does changing a priority queue element result in resorting the queue?

依然范特西╮ 提交于 2019-12-03 20:09:48

问题


I have a priority_queue, and I want to modify some of it's contents (the priority value), will the queue be resorted then?

It depends if it resorts on push/pop (more probable, becouse you just need to "insert", not resort whole), or when accessing top or pop.

I really want to change some elements in the queue. Something like that:

priority_queue<int> q;

int a=2,b=3,c=5;
int *ca=&a, *cb=&b, cc=&c;

q.push(a);
q.push(b);
q.push(c); //q is now {2,3,5}

*ca=4;

//what happens to q?
// 1) {3,4,5}
// 2) {4,2,5}
// 3) crash

回答1:


priority_queue copies the values you push into it. Your assignment at the end there will have zero effect on the order of the priority queue, nor the values stored inside of it.




回答2:


Unfortunately, the std::priority_queue class doesn't support the increase/decrease_key operations that you're looking for. Of course it's possible to find the element within the heap you want to update, and then call make_heap to restore the binary heap invariants, but this can't be done as efficiently as it should be with the std:: container/algorithms. Scanning the heap to find the item is O(N) and then make_heap is O(N) on top of that - it should be possible to do increase/decrease_key in O(log(N)) for binary heaps that properly support updates.

Boost provides a set of priority queue implementations, which are potentially more efficient than the std::priority_queue (pairing heaps, Fibonacci heaps, etc) and also offer mutability, so you can efficiently perform dynamic updates. So all round, using the boost containers is potentially a much better option.




回答3:


Okay, after searching a bit I found out how to "resort" queue, so after each priority value change you need to call:

std::make_heap(const_cast<Type**>(&queue.top()),
     const_cast<Type**>(&queue.top()) + queue.size(),
     ComparerClass());

And queue must be then

std::priority_queue<Type*,vector<Type*>,ComparerClass> queue;

Hope this helps.




回答4:


I stumbled on this issue while considering the use of priority queues for an A* algorithm.

Basically, C++ priority queues are a very limited toy.

Dynamically changing the priority of a queued element requires to perform a complete reconstruction of the underlying heap manually, which is not even guaranteed to work on a given STL implementation and is grossly inefficient.
Besides, reconstructing the heap requires butt-ugly code, which would have to be hidden in yet another obfuscated class/template.

As for so many other things in C++, you'll have to reinvent the wheel, or find whatever fashionable library that reinvented it for you.



来源:https://stackoverflow.com/questions/14016189/does-changing-a-priority-queue-element-result-in-resorting-the-queue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!