如何迭代priority_queue?

min*_*a70 59 c++ queue stl

我可以使用迭代器(如a )遍历c ++中的标准priority_queue或标准吗?我不想使用pop,因为它导致我的队列出列.queuevector

谢谢你的帮助

xan*_*xan 22

priority_queue 不允许迭代所有成员,大概是因为它会使队列的优先级排序无效(通过修改你遍历的元素)或者可能是"不是我的工作"的理由.

官方的解决方法是使用一个vector而不是自己管理优先级make_heap,push_heappop_heap.在理查德的回答中,另一个解决方法是使用派生自priority_queue并访问具有protected可见性的底层存储的类.

  • “因为很容易使队列的优先级排序无效(通过修改您遍历的元素)”返回 const 迭代器是可能的。就像 map 返回迭代器一样,其中 key 是常量。 (5认同)
  • 这应该在文档中,以使我们知道有限的priority_queue的用处是多么的……叹气。 (2认同)

Ric*_*ard 12

你可以这样做 - bam!请注意,项目在队列中时不一定处于"排序"顺序,至少在容器的直接迭代方面.

#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;
}
Run Code Online (Sandbox Code Playgroud)

  • 子类化std :: containers是危险/错误的,因为它们缺少虚拟析构函数. (3认同)

mar*_*cog 10

queue目的地提供有限的接口,其排除迭代.但由于a queue使用a 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;
}
Run Code Online (Sandbox Code Playgroud)

优先级队列的类似答案:不,你不能.但在这种情况下,vector默认使用a .在任何情况下,您都无法访问底层容器来迭代它们.请参阅此问题以供进一步阅读.

  • 我想我会为你的问题添加答案"为什么不直接使用双端队列?" 在我的场景中,我想记录priority_queue的内容而不影响实现(通过更改类型).这是一项日志工作,其中性能并不重要,因此制作副本可以正常工作. (3认同)
  • 您能否将答案的“否”部分提升到顶部。坦率地说,我不明白为什么 deque,它与问题无关。 (3认同)

Lie*_*yan 5

是的,复制 priority_queue 并迭代它。

  • 如果不考虑性能,这听起来是一个合理的想法。如果您提供代码片段,您将得到我的支持。 (11认同)

Sno*_*oze 5

#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;
}
Run Code Online (Sandbox Code Playgroud)

  • `std::priority_queue` 没有 `push_back` 方法。它有一个“push”方法。 (3认同)

Bjö*_*lex 3

这不可能。您将不得不使用不同的容器,可能deque最适合您。