我想知道为什么在使用priority_queue
创建最小堆时,应该使用std::greater
?
std::priority_queue<T, std::vector<T>, std::greater<T> > min_heap;
对我来说,由于最小值总是位于堆的顶部,所以应该使用std::less
类。
更新:
另一方面,由于priority_queue
(最大堆)的默认行为是将最大值保持在顶部,因此看起来应该使用std::greater
来创建最大堆而不是最小堆。
我想知道为什么在使用priority_queue
创建最小堆时,应该使用std::greater
?
std::priority_queue<T, std::vector<T>, std::greater<T> > min_heap;
对我来说,由于最小值总是位于堆的顶部,所以应该使用std::less
类。
更新:
另一方面,由于priority_queue
(最大堆)的默认行为是将最大值保持在顶部,因此看起来应该使用std::greater
来创建最大堆而不是最小堆。
std::priority_queue
是一个容器适配器;对于诸如std::vector
等序列容器,基本的内存考虑使得后端成为修改的首选位置(使用pop_back()
和push_back()
)。priority_queue
的原语基于std::make_heap
(构造函数)、std::pop_heap
+container::pop_back
(priority_queue::pop
)以及container::push_back
+std::push_heap
(priority_queue::push
)。pop_heap
将会取出底层存储的前端并将其放置在后端,然后恢复堆不变式。push_heap
则相反。max_heap
上执行sort_heap
(初始时最大值在前面)将反复将前端元素移到后面并根据默认比较运算符less
对范围进行排序。max_heap
的首选方法是将相对于less
具有最大值的元素放在前面,并通过priority_queue::top
(底层container::front
)访问。std::less
比较器的priority_queue
是否直观地表示了一个max_heap
。通过在调用各种堆函数时反转比较器的参数(但请参见@T.C.的评论,使用C++98绑定器会非常冗长),可以将其定义为min_heap
。对我来说,唯一不直观的结果是top()
将无法给出具有最高优先级的元素。is_heap
和 is_heap_until
。 - TemplateRexfirst_argument_type
和 second_argument_type
。 - TemplateRexmake_heap
、push_heap
和pop_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
需要一个最大堆。less
会导致最大堆,而 greater
则会导致最小堆的问题。 - Sebastian Redlstd::sort
相同的排序顺序,并使用相同的比较运算符,那么从最大堆中实现std::sort_heap
肯定更容易(也更有效率)。这个事实可能有助于推理过程。 - Benjamin Lindley这是一个将优先队列转换为排序序列的过程。
我们如何实现呢?
假设我们现在有一个最大堆,我们采取以下步骤。
HEAP-SORT(A)
for i = A.heap_size downto 2
exchange A[1] with A[A.heap_size]
A.heapsize -= 1
max_heapify(A)
priority_queue
是一种数据结构,它以这样的方式存储元素,使得具有最高优先级的元素始终位于队列顶部。默认情况下,元素的优先级由其值确定。但是,您可以使用函数对象来改变元素优先级的确定方式。
函数对象是一个小型函数对象,可用于执行特定任务。在这种情况下,greater<int>
函数对象用于比较两个整数,并在第一个整数大于第二个整数时返回 true。
当您将 greater<int>
函数对象与 priority_queue
一起使用时,具有最低值的元素将被视为具有最高优先级。这是因为当比较具有最低值的元素与任何其他元素时,greater<int>
函数对象将始终返回 true。