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

cmssoen2  于 2023-03-14  发布在  其他
关注(0)|答案(3)|浏览(171)

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

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

对我来说,由于最小值总是位于堆的顶部,因此所使用的类应该是std::less

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

s71maibg

s71maibg1#

逻辑论证如下

  1. std::priority_queue是容器适配器;基本的存储器考虑使得后面成为修改诸如X1 M3 N1 X的序列容器(具有X1 M1 N1 X和X1 M2 N1 X)的优选位置。
  2. priority_queue原语基于std::make_heap(构造函数)、std::pop_heap + container::pop_backpriority_queue::pop)和container::push_back + std::push_heappriority_queue::push
  3. pop_heap将占用底层存储的 front,并将其放在 back,然后恢复堆不变式。
    1.在max_heap上执行sort_heap(最大值最初在前面)将repeatedly pop the front to the back并根据less(默认比较运算符)对范围排序
    1.因此X1 M17 N1 X的优选实现是在前端具有通过X1 M19 N1 X(底层X1 M20 N1 X)访问的最大元素W.R.T.less
    1.我们仍然可以争论,带有std::less比较器的priority_queue是否直观地表示max_heap。通过反转比较器的参数,它可以被定义为min_heap(但是请看@T.C.的评论,对于C++98绑定器,这是相当冗长的)在对各种堆函数的调用中无处不在。(对我来说)反直觉的结果是top()不会给元素 top 优先级
aurhwmvo

aurhwmvo2#

C堆函数make_heappush_heappop_heapmax heap上操作,这意味着当使用默认比较器时,顶部元素是 maximum。因此,要创建最小堆,需要使用greater<T>而不是less<T>
我怀疑使用max堆而不是min堆是因为less操作更容易实现,在C
中,less具有特权,可以作为所有STL算法的“默认”比较器;如果您只打算实现一个比较操作(而不是==),那么它应该是<,这会导致priority_queue<T, C<T>, less<T>>表示最大队列而priority_queue<T, C<T>, greater<T>>表示最小队列的不幸情况。
此外,某些算法(如nth_element)需要最大堆。

qxgroojn

qxgroojn3#

它是一个将优先级队列转换为有序序列的过程。
我们如何才能做到这一点?
假设我们现在有一个最大堆,我们采取以下步骤。

HEAP-SORT(A)
    for i = A.heap_size downto 2
        exchange A[1] with A[A.heap_size]
        A.heapsize -= 1
        max_heapify(A)

当我们完成这个过程时,我们得到一个增序序列。
我们注意到每次比较两个元素时,我们总是把大的放回数组,这意味着小的在大的左边.
这与我们向std::sort算法传递一个less操作符以获得一个递增顺序序列的想法是一致的。

相关问题