使用`std :: greater`通过`priority_queue`创建最小堆的原因

时间:2015-09-23 19:36:01

标签: c++ c++11 heap priority-queue min-heap

我想知道为什么使用priority_queue创建最小堆,应该使用std::greater

std::priority_queue<T, std::vector<T>, std::greater<T> > min_heap;

对我而言,由于最小值始终位于堆的顶部,因此使用的类应为std::less

更新 另一方面,由于priority_queue(最大堆)的默认行为是在顶部保持最大值,因此我认为std::greater应该用于最大堆创建而不是用于创建最小堆

3 个答案:

答案 0 :(得分:8)

C ++堆函数make_heappush_heappop_heapmax heap上运行,这意味着使用时顶部元素是最大值默认比较器。因此,要创建最小堆,您需要使用greater<T>而不是less<T>

我怀疑使用最大堆而不是最小堆是因为使用less操作更容易实现。在C ++中,less具有成为所有STL算法的“默认”比较器的特殊权限;如果您只是要实现一个比较操作(==除外),它应该是<。这导致了不幸的怪癖,priority_queue<T, C<T>, less<T>>表示最大队列,priority_queue<T, C<T>, greater<T>>表示最小队列。

此外,像nth_element这样的某些算法需要最大堆。

答案 1 :(得分:6)

逻辑参数如下

  1. std::priority_queue是容器适配器;基本内存注意事项使后面成为序列容器(例如pop_back())的修改(push_back()std::vector)的首选位置。
  2. priority_queue原语基于std::make_heap(构造函数),std::pop_heap + container::pop_backpriority_queue::pop)和container::push_back + {{ 1}}(std::push_heap
  3. priority_queue::push将获取底层存储的,并将其放在后面,之后恢复堆不变量。相反的是pop_heap
  4. push_heap上执行sort_heap(最初在前面有最大值)将repeatedly pop the front to the back并根据max_heap(默认比较运算符)对范围进行排序
  5. 因此,less的首选实现是使最大元素为w.r.t.前面max_heap,通过less(基础priority_queue::top)访问。
  6. 人们仍然可以辩论container::frontpriority_queue比较器代表std::less是否直观。它可以被定义为max_heap通过反转比较器的参数(但是看看@TC的注释,对于C ++ 98绑定器,这是相当冗长的)在各种堆函数的调用中无处不在。一个(对我来说)反直觉的结果是min_heap然后没有给出具有 top 优先级的元素

答案 2 :(得分:0)

http://en.cppreference.com/w/cpp/container/priority_queuepriority_queue旨在将最大值放在顶部。如果您使用默认的std::less比较器,则会发生这种情况。因此,如果您想要反向行为,则需要使用反向比较器std::greater