如何迭代一个priority_queue?

我可以通过迭代器(如vector )在c ++中遍历标准的priority_queue或标准queue吗? 我不想使用popup,因为它导致我的队列出列。

谢谢你的帮助

一个queue专门提供了一个有限的接口,不包括迭代。 但是由于queue使用deque作为底层容器,为什么不直接使用deque

 #include <iostream> #include <queue> using namespace std; int main() { deque<int> q; q.push_back(1); q.push_back(2); q.push_back(3); for(deque<int>::iterator it = q.begin(); it != q.end(); ++it) cout << *it << endl; } 

一个优先级队列类似的答案:不,你不能。 在这种情况下,默认使用vector 。 在任何情况下,您都不能访问底层容器来遍历它们。 看到这个问题进一步阅读。

你可以这样做 – 巴姆! 注意,项目在队列中不一定处于“sorting”顺序,至less在容器的直接迭代方面是这样。

 #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; } 

是的,制作一个priority_queue的副本并迭代它。

priority_queue不允许遍历所有的成员,大概是因为在队列的优先顺序无效(通过修改你遍历的元素)或者这是一个“不是我的工作”的基本原理。

正式的解决方法是使用vector来代替,并使用make_heappush_heappop_heap自己pipe理优先级。 在理查德的回答中,另一个解决方法是使用派生自priority_queue的类并访问protected可见性的底层存储。

这不可能。 你将不得不使用一个不同的容器,可能一个deque将最好地为您服务。

 #include <queue> #include <iostream> int main() { std::priority_queue<int> pq; pq.push_back(1); pq.push_back(2); pq.push_back(3); std::priority_queue<int> temp = pq; while (!temp.empty()) { std::cout << temp.top() << std::endl; temp.pop(); } return 0; } 

队列与vector完全不同,用于不同的目的。 优先级队列是简单的sorting的deques,没有直接访问后面。 然而,如果你拼命地想要这样做,你可以做的是从顶部/前部元素popup,将其添加到列表/数组/vector,然后将元素推回到您的队列中(size_t i = 0;我<q.size(); i ++)。 我在java数据结构中学习了一门课,这是考试问题的答案。 另外这是我能想到的唯一方法。

我绊倒了你的问题后,我发现了这个。 通过编写一个从std :: priority_queueinheritance的实现有一个非常简单的方法。 全是14条线。

http://www.linuxtopia.org/online_books/programming_books/c++_practical_programming/c++_practical_programming_189.html

我自己也有同样的问题。 我发现到达优先级队列底层的数据结构是非常困难的,也许是不可能的。 在我的情况下,这是一个对象的vector。

但是,我结束了使用标准的模板库堆。 它几乎和优先级队列一样简单(它需要两个指令push和pop,而pq为1),否则行为似乎是相同的,如果我不修改它,我可以得到底层的数据结构。

C ++ priority_queue不提供.begin()指针(就像vector一样),您可以使用它来迭代它。

如果你想迭代优先级队列来search它是否包含一个值,那么可能会创build一个包装优先级队列,并使用一个散列集来跟踪你在队列中的含义。

 class MyPriorityQueue { MyPriorityQueue() {} void push(int item) { if (!contains(item)){ pq_.push(item); set_.emplace(item); } } void pop() { if (!empty()) { int top = pq_.top(); set_.erase(top); pq_.pop(); } } int top() { return pq_.top(); } bool contains(int item) { return set_.find(item) != set_.end(); } bool empty() const { return set_.empty(); } private: std::priority_queue<int> pq_; std::unordered_set<int> set_; }; 

这些答案中的许多依赖于编码/使用许多C ++的神秘function。 没关系,娱乐和资助昂贵的程序员。 一个直接的解决scheme是快速,便宜的编程,但更昂贵的运行,是:

 // // Only use this routine when developing code, NOT for production use!! // // Note. _pq is in private for a class that uses the priority queue // and listQueue is a public method in that same class. // void listQueue() { // allocate pointer to a NEW container priority_queue<int>* new_pq = new priority_queue<int>; while (!_pq->empty()) { int el = _pq->top(); cout << "(" << el << ")" << endl; new_pq->push(el); _pq->pop(); } // end while; // remove container storage delete(_pq); // viola, new container same as the old _pq = new_pq; } // end of listQueue; 

顺便说一下,不要为priority_queue提供一个迭代器,尤其是当它是一个or结构的容器类时。

我有同样的问题,我想迭代优先级队列没有出队(因此摧毁我的队列)。 我通过将我的priority_queue指针重新指向一个指向vector的指针(因为我的priority_queue使用vector作为它的容器)而使它适用于我。 以下是它的样子:

 class PriorityQueue { private: class Element { int x; //Other fields ... .. //Comparator function bool operator()(const Element* e1, const Element* e2) const { // Smallest deadline value has highest priority. return e1->x > e2->x; } }; // Lock to make sure no other thread/function is modifying the queue // Ofcourse we can do our operation w/o lock. if we are sure what is happening in other functions pthread_mutex_t lock; std::priority_queue<Element*, std::vector<Element*>, Element> pq; public: PriorityQueue(); ~PriorityQueue(); //print the all the elements of the queue void print_queue_elements() { std::vector<PriorityQueue::Element*> *queue_vector; //Acquire the lock pthread_mutex_lock(&lock); //recast the priority queue to vector queue_vector = reinterpret_cast<std::vector<PriorityQueue::Element*> *>(&pq); for(std::vector<PriorityQueue::Element*>::iterator it = (*queue_vector).begin(); it != (*queue_vector).end(); it++) { //Assuming Element class has string function printf("My Element %s", (*it)->string); //other processing with queue elements } //Release the lock pthread_mutex_unlock(&lock); } //other functions possibly modifying the priority queue ... .. . }; 

现在,因为我正在使用reinterpret_cast,人们可以争论types安全。 但在这种情况下,我确信所有其他函数访问/更改队列(所有这些都是安全的)..我觉得这是比整个队列的内容复制到其他容器好多了。

我实际上期望static_cast工作..因为priority_queue适配器上的容器(在我们的情况向量),但它不,我不得不使用reinterpret_cast