Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to iterate over a priority_queue?

Tags:

c++

stl

queue

Can I traverse a standard priority_queue or standard queue in c++ with an iterator (like a vector)? I don't want to use pop because it cause my queue to be dequeued.

Thanks for any help

like image 576
mina70 Avatar asked Dec 19 '10 19:12

mina70


People also ask

Can you iterate over a priority queue?

You can't traverse a Priority Queue in that order because of the underlying implementation (I think it's min-heap in Java). It's not a sorted array, so that you can just go from one element to the one with the lesser priority.

Can you iterate through a priority queue in python?

The PriorityQueue is implemented as binary heap, which is implemented using a list (array) in python. To iterate over the queue you need to know the rules about where children are stored in the list.

How do you iterate through a STD list?

Create an iterator of std::list. Point to the first element. Keep on increment it, till it reaches the end of list. During iteration access, the element through iterator.

Can we iterate in queue?

In other words, std::queue is not meant to be iterated over. If you need to iterate over a std::queue , you can create a copy of it and remove items from the copy, one at a time, using the standard pop function after processing it. This way the original queue remains untouched, but its copy becomes empty.


2 Answers

priority_queue doesn't allow iteration through all the members, presumably because it would be too easy in invalidate the priority ordering of the queue (by modifying the elements you traverse) or maybe it's a "not my job" rationale.

The official work-around is to use a vector instead and manage the priority-ness yourself with make_heap, push_heap and pop_heap. Another work-around, in @Richard's answer, is to use a class derived from priority_queue and access the underlying storage which has protected visibility.

like image 111
xan Avatar answered Sep 27 '22 22:09

xan


You can do it like this - bam! Notice that items are not necessarily in "sorted" order while they are in the queue, at least with regards to a straight-forward iteration of the container.

#include <queue> #include <cstdlib> #include <iostream> using namespace std;  template <class T, class S, class C> S& Container(priority_queue<T, S, C>& q) {     struct HackedQueue : private priority_queue<T, S, C> {         static S& Container(priority_queue<T, S, C>& q) {             return q.*&HackedQueue::c;         }     };     return HackedQueue::Container(q); }  int main() {     priority_queue<int> pq;     vector<int> &tasks = Container(pq);      cout<<"Putting numbers into the queue"<<endl;     for(int i=0;i<20;i++){         int temp=rand();         cout<<temp<<endl;         pq.push(temp);     }      cout<<endl<<"Reading numbers in the queue"<<endl;     for(vector<int>::iterator i=tasks.begin();i!=tasks.end();i++)         cout<<*i<<endl;      cout<<endl<<"Taking numbers out of the queue"<<endl;     while(!pq.empty()){         int temp=pq.top();         pq.pop();         cout<<temp<<endl;     }      return 0; } 
like image 32
Richard Avatar answered Sep 27 '22 21:09

Richard