如何迭代priority_queue?
我可以使用迭代器(如 vector
)遍历 C++ 中的标准 priority_queue
或标准 queue
吗?我不想使用 pop,因为它会导致我的队列出队。
感谢您的帮助
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
队列有目的地提供有限的接口,其中排除了迭代。但既然
queue
使用deque
作为底层容器,为什么不直接使用deque
呢?对于优先级队列的类似答案:不,你不能。但在本例中,默认使用
向量
。在这两种情况下,您都无法访问底层容器来迭代它们。请参阅此问题以进一步阅读。A
queue
purposefully provides a limited interface, which excludes iteration. But since aqueue
uses adeque
as the underlying container, why not use adeque
directly?Similar answer for a priority queue: no, you cannot. In this case though, a
vector
is used by default. In neither case can you access the underlying container to iterate over them. See this question for further reading.是的,复制priority_queue并对其进行迭代。
Yes, make a copy of the priority_queue and iterate over that.
这是不可能的。您必须使用不同的容器,可能是
deque
将为您提供最好的服务。This is not possible. You would have to use a different container, probably a
deque
would serve you best.我在偶然发现你的问题后发现了这一点。有一种非常简单的方法可以通过编写继承自 std::priority_queue 的实现来实现此目的。全部是14行。
http://www.linuxtopia.org/online_books/programming_books /c++_practical_programming/c++_practical_programming_189.html
I found this after stumbling across your question. There is a very simple way of doing this by writing an implementation inheriting from std::priority_queue. It is all of 14 lines.
http://www.linuxtopia.org/online_books/programming_books/c++_practical_programming/c++_practical_programming_189.html
队列与向量完全不同,并且用于不同的目的。优先级队列只是排序的双端队列,无法直接访问后面。但是,如果您迫切希望对任何方法执行此操作,您可以做的就是弹出顶部/前面的元素,将其添加到列表/数组/向量中,然后将该元素推回到队列中 for(size_t i = 0; q.size();我参加了 Java 数据结构课程,这是考试问题的答案。而且这是我能想到的唯一方法。
Queues are totally different from vectors and are used for different purposes. Priority queues are simply sorted deques with no direct access to the back. However, if you desperately want to do this for whatever method, what you can do is pop off the top/front element, add it to a list/array/vector, and then push the element back into your queue for(size_t i = 0; i < q.size(); i++). I took a class in java data structures, and this was the answer to an exam question. Plus it is the only method i can think of.
其中许多答案依赖于编码/使用许多 C++ 神秘功能。没关系,既有趣又可以为昂贵的程序员提供资金。一个快速、编程成本低但运行成本更高的直接解决方案是:
顺便说一句,不为priority_queue提供迭代器似乎完全不明智,特别是当它是 or 结构的容器类时。
Many of these answers rely on coding/using many of C++ arcane features. That's ok, fun and funds expensive programmers. A direct solution that is quick, cheap to program but more expensive to run, is:
By the way, it seems perfectly non-sensible to NOT provide an iterator for a priority_queue, especially when it is a container class for a or structure.
大多数现有答案要么建议使用不同的数据结构,要么执行一系列
O(log n)
操作(n
是优先级队列的大小)。有些人甚至建议复制该结构。该操作可以相对于元素数量以线性时间执行,前提是:
如果满足这些条件,则可以使用以下代码:
这种方法的优点是不更改所使用的数据结构:如果二进制堆适合您的应用程序,则使用多重集是没有意义的。而且它结构紧凑,实现起来很简单,不会改变原始对象,也不需要额外的内存。最后,它的运行时间为
O(n)
,而不是常见的O(n log n)
。Most existing answers either suggest using a different data structure or performing a sequence of
O(log n)
operations (n
being the size of the priority queue). Some even advise to make a copy of the structure.The operation can be performed in linear time with respect to the number of elements, provided that :
If these conditions are met, the following code can be used :
This approach has the advantage of not changing the data structure used : if a binary heap is suited for your application, there is no point in using a multiset. Also it is compact, trivial to implement, does not change the original object and does not require additional memory. Finally, it runs in
O(n)
time instead of the commonly seenO(n log n)
.C++priority_queue 不提供可用于迭代它的 .begin() 指针(如向量那样)。
如果您想迭代优先级队列以搜索它是否包含值,那么可以创建一个包装器优先级队列并使用哈希集来跟踪队列中的内容。
C++ priority_queue does not offer a .begin() pointer (like vector would do) that you can use to iterate over it.
If you want to iterate over the priority queue to search for whether it contains a value then maybe create a wrapper priority queue and use a hash set to keep track of what you have in the queue.
出于基本目的,
std::multiset
将为您提供类似的属性,但具有迭代能力:Less
For basic purposes, a
std::multiset
will give you similar properties but with the ability to iterate:Less
can be defined制作副本并迭代 - 由 @lie-ryan 建议
Making a copy and iterating over that - suggested by @lie-ryan
我自己也有同样的疑问。我发现要了解优先级队列底层的数据结构非常困难,甚至可能是不可能的。就我而言,这是一个对象向量。
但是,我最终使用了标准模板库堆。它几乎和优先级队列一样简单(它需要两条指令来推送和弹出,而 pq 则需要 1 条指令),否则行为似乎是相同的
和
如果我不修改它,我可以获取底层数据结构。
I had the same question myself. I found it was very difficult, maybe impossible, to get to the data structure underlying the priority queue. In my case this was a vector of objects.
However, I ended up using a standard template library heap. It is almost as easy as a priority queue (it takes two instructions to push and pop, vs. 1 for the pq), otherwise the behavior seems to be identical
and
I can get at the underlying data structure if I don't modify it.
如果你想以复杂度(logN)的有序方式推送项目。但如果还想按升序迭代元素,您可以使用
set
。集合通常被实现为二叉搜索树。
集合是可迭代的(开始、结束、rbegin、rend 等)
If you want to push items in an ordered manner with complexity (logN). But would like to iterate over the elements as well in increasing order, you can use
set<int>
.Sets are typically implemented as binary search trees.
Sets are iterable (begin, end, rbegin, rend etc)
我遇到了同样的问题,我想迭代优先级队列而不出队(因此破坏了我的队列)。我通过将priority_queue指针重新转换为指向向量的指针(因为我的priority_queue使用向量作为其容器)使其对我有用。它是这样的:
现在由于我使用reinterpret_cast,人们可以争论类型安全。但在这种情况下,我确信所有其他功能都可以访问/更改队列(所有这些功能都是安全的)..而且我觉得这是比将整个队列的内容复制到其他容器更好的方法。
我实际上期望
static_cast
能够工作..因为priority_queue是容器上的适配器(在我们的例子中是向量),但事实并非如此,我不得不使用reinterpret_cast
。I had the same problem, where I wanted to iterate over a priority queue without dequeuing (hence destroying my queue). I made it work for me by recasting my priority_queue pointer to a pointer to a vector (as my
priority_queue
uses vector as its container). Here is how it looks like:Now since I am using reinterpret_cast, people can argue about type-safety. But in this case I am sure about all other functions accessing/changing the queue (all of which are safe).. and I feel this is a much better way than copying the content of whole queue to some other container.
I was actually expecting
static_cast
to work.. as priority_queue is adaptor over container (vector in our case), but it doesnt and I had to usereinterpret_cast
.priority_queue
不允许迭代所有成员,大概是因为很容易使队列的优先级排序无效(通过修改您遍历的元素),或者这可能是“不是我的工作”理由。官方的解决方法是使用
vector
并使用make_heap
、push_heap
和pop_heap
自行管理优先级代码>.在 @Richard 的回答中,另一个解决方法是使用从priority_queue
派生的类并访问具有protected
可见性的底层存储。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 withmake_heap
,push_heap
andpop_heap
. Another work-around, in @Richard's answer, is to use a class derived frompriority_queue
and access the underlying storage which hasprotected
visibility.你可以这样做 - 砰!请注意,项目在队列中时不一定按“排序”顺序,至少对于容器的直接迭代而言是如此。
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.