C++ 使用'std::greater'通过'priority_queue'创建最小堆的原因`
我想知道为什么要使用C++ 使用'std::greater'通过'priority_queue'创建最小堆的原因`,c++,c++11,heap,priority-queue,min-heap,C++,C++11,Heap,Priority Queue,Min Heap,我想知道为什么要使用priority\u队列创建最小堆,应该使用std::greater std::priority_queue<T, std::vector<T>, std::greater<T> > min_heap; std::优先级队列最小堆; 对我来说,因为最小的值总是位于堆的顶部,所以使用的类应该是std::less 更新: 另一方面,由于PrimyIyQueLe>/Cuff>(max HeAP)的默认行为是在顶部保持最大值,所以我认为, ST
priority\u队列
创建最小堆,应该使用std::greater
std::priority_queue<T, std::vector<T>, std::greater<T> > min_heap;
std::优先级队列最小堆;
对我来说,因为最小的值总是位于堆的顶部,所以使用的类应该是std::less
更新:
另一方面,由于
pop_heap
对a进行操作,这意味着使用默认比较器时顶部元素是最大值。因此,要创建最小堆,需要使用greater
而不是less
我怀疑使用最大堆而不是最小堆是因为使用
less
操作更容易实现。在C++中,<>代码> < >作为所有STL算法的“默认”比较器的特殊特权;如果您只打算实现一个比较操作(而不是==
),则应该是请参阅。优先级队列
设计用于将最大值置于顶部。如果使用默认的std::less
比较器,就会发生这种情况。因此,如果您想要反向行为,您需要使用反向比较器,std::greater
逻辑参数如下
std::priority_queue
是一个容器适配器;对于序列容器(如std::vector
),基本内存考虑使背面成为修改的首选位置(使用pop_back()
和push_back()
)李>
priority\u queue
原语基于std::make\u heap
(构造函数),std::pop\u heap
+container::pop\u back
(priority\u queue::pop
)和container::push\u back
(priority\u queue::push
)
pop_heap
将占用底层存储的前面,并将其放在后面,然后恢复堆不变量。与之相反的是push\u heap
在max\u heap
上执行sort\u heap
(max最初位于前面)将根据less
对范围进行排序(这是默认的比较运算符)
因此,max_heap
的首选实现是将max元素w.r.t.less
放在前端,通过priority_queue::top
(底层container::front
)访问李>
我们仍然可以争论,带有std::less
比较器的priority\u队列
表示max\u堆
是否直观。它可以通过反转比较器的参数来定义为min_heap
(但请参见@T.C.的评论,对于C++98绑定,这相当冗长),在对各种堆函数的调用中无处不在。一个(对我来说)违反直觉的结果是top()
不会给元素赋予最高优先级
你在找什么?我现在正在读cppreference.com,他们指定std::less作为默认值,并说替换std::greater将导致最小元素显示为“top”,而不是最大元素。这似乎是一个惯例问题,不是吗?我认为这是一个很好的问题。我觉得很奇怪,我发现很少有人质疑这个具体的设计决定。到目前为止,你是唯一一个,像我一样,似乎觉得这个比较器的“反向”使用非常违反直觉的人。我不会质疑这个决定背后的性能原因,但这对我来说并不自然。我只是在回答另一个问题时遇到了这个问题,在编写自己的比较器时感觉特别不自然。这并不能回答为什么使用更少的会导致最大堆的问题,而更大
会导致最小堆。请参阅我的编辑,但TL;Dmax是Head在C++中的其他地方使用,所以它们是默认的。所以,让我看看我是否正确理解了。你的意思是因为less
是默认的比较器,而且max\u heap
更有用,所以我们最终得到了一个max\u heap
,它是通过less
实现的,而不是greater
?我不认为max heap比使用less的min heap更容易实现。但是,从最大堆实现std::sort_heap
当然更容易(也更有效),前提是使用相同的比较运算符,您需要从std::sort
获得相同的顺序。这一事实可能是原因之一。@TemplateRex:因为当您从堆中弹出一个元素时,在最后会留下一个空间,您可以在这里放置刚刚弹出的元素(这是最大的元素)。如果你从最小堆开始,为了得到正确的顺序,你必须在完成时反转范围。但是为什么我应该使用less
而不是greater
来将最大值放在顶部呢?meow\u堆
算法肯定在C++98中。@T.C.你是对的,更新了,只有是_heap
并且是_heap _,直到
被相加为止。因此,不能对比较器求反;您需要一个交换参数顺序的包装器。给定原始C++的TMP是如何设计的(所有的<代码> PrtHyfy/Bun1/BID2D/COM>乐趣),我并不感到惊讶,他们没有这样做。很容易忘记旧活页夹的痛苦,还必须提取第一个参数类型
和第二个参数类型
有人能再次解释第5点吗?从我的理解来看,弹出el