[英]The reason of using `std::greater` for creating min heap via `priority_queue`
I am wondering why for creating a min heap using the priority_queue
, the std::greater
should be used?我想知道为什么使用priority_queue
创建最小堆,应该使用std::greater
?
std::priority_queue<T, std::vector<T>, std::greater<T> > min_heap;
To me, since the smallest value is always located at the top of the heap, the employed class should be std::less
对我来说,因为最小值总是位于堆的顶部,所以使用的类应该是std::less
Update: On the other hand, since the default behavior of priority_queue
(max heap) is to hold the greatest value at the top, it looks to me that the std::greater
should be used for the max heap creation and not for min heap creation更新:另一方面,由于priority_queue
(最大堆)的默认行为是在顶部保存最大值,在我看来std::greater
应该用于创建最大堆而不是最小堆创建
The logical argument is as follows逻辑论证如下
std::priority_queue
is a container adaptor; std::priority_queue
是一个容器适配器; basic memory considerations make the back the preferred place for modifications (with pop_back()
and push_back()
) for sequence containers such as std::vector
.基本内存考虑使 back 成为对序列容器(如std::vector
pop_back()
进行修改(使用pop_back()
和push_back()
)的首选位置。priority_queue
primitives are based on std::make_heap
(constructor), std::pop_heap
+ container::pop_back
( priority_queue::pop
) and on container::push_back
+ std::push_heap
( priority_queue::push
) priority_queue
原语基于std::make_heap
(constructor)、 std::pop_heap
+ container::pop_back
( priority_queue::pop
) 和container::push_back
+ std::push_heap
( priority_queue::push
)pop_heap
will take the front of the underlying storage, and put it at the back , restoring the heap invariant afterwards. pop_heap
会取底层存储的前面,放在后面,之后恢复堆不变性。 The reverse goes for push_heap
. push_heap
。sort_heap
on a max_heap
(with the max at the front initially) will repeatedly pop the front to the back and sort the range according to less
(which is the default comparison operator)做sort_heap
上的max_heap
(具有最大在前面最初)将反复弹出前面到后面和排序根据范围less
(即默认比较运算符)max_heap
is to have the max element wrt less
at the front, accessed through priority_queue::top
(underlying container::front
).因此, max_heap
的首选实现是让 max 元素在前面less
,通过priority_queue::top
(底层container::front
)访问。priority_queue
with a std::less
comparator is representing a max_heap
.人们仍然可以争论,带有std::less
比较器的priority_queue
表示max_heap
是否直观。 It could have been defined as a min_heap
by reversing the comparator's arguments (but see the comment by @TC that with C++98 binders this is rather verbose) everywhere in the calls to the various heap functions.它可以通过在对各种堆函数的调用中的任何地方反转比较器的参数(但请参阅@TC 的评论,使用 C++98 绑定器,这相当冗长)来定义为min_heap
。 The one (for me) counter-intuitive result would have been that top()
would then not have given the element with top priority一个(对我来说)违反直觉的结果是top()
不会给元素以最高优先级The C++ heap functions make_heap
, push_heap
, and pop_heap
operate on a max heap , meaning the top element is the maximum when using the default comparator. C++ 堆函数make_heap
、 push_heap
和pop_heap
在最大堆上运行,这意味着使用默认比较器时,顶部元素是最大值。 So, to create a min-heap, you need to use greater<T>
instead of less<T>
.因此,要创建最小堆,您需要使用greater<T>
而不是less<T>
。
I suspect that a max heap is used instead of a min heap is that it is easier to implement with the less
operation.我怀疑使用最大堆而不是最小堆是因为使用less
操作更容易实现。 In C++, less
has the special privilege of being the sort of "default" comparator for all STL algorithms;在 C++ 中, less
具有作为所有 STL 算法的“默认”比较器的特殊特权; if you only are going to implement one comparison operation (other than ==
), it should be <
.如果您只打算实现一个比较操作(除了==
),它应该是<
。 This leads to the unfortunate quirk that priority_queue<T, C<T>, less<T>>
means a max-queue and priority_queue<T, C<T>, greater<T>>
means a min-queue.这导致了一个不幸的怪癖, priority_queue<T, C<T>, less<T>>
意味着一个最大队列,而priority_queue<T, C<T>, greater<T>>
意味着一个最小队列。
Also, certain algorithms like nth_element
need a max-heap.此外,某些算法(如nth_element
需要最大堆。
See http://en.cppreference.com/w/cpp/container/priority_queue .请参阅http://en.cppreference.com/w/cpp/container/priority_queue 。 A priority_queue
is designed to put the largest value at the top. priority_queue
旨在将最大值放在顶部。 This happens if you use the default std::less
comparator.如果您使用默认的std::less
比较器,就会发生这种情况。 So if you want the reverse behavior, you need to use the reverse comparator, std::greater
.因此,如果您想要反向行为,则需要使用反向比较器std::greater
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.