请考虑以下代码,
using namespace std;
std::priority_queue<int,vector<int>,std::greater<int>> queue; //first
queue.push(26);
queue.push(12);
queue.push(22);
queue.push(25);
std::cout<<queue.top()<<endl;
std::priority_queue<int,vector<int>,std::less<int>> queue2; //second
queue2.push(26);
queue2.push(12);
queue2.push(22);
queue2.push(25);
std::cout<<queue2.top()<<endl;
输出:
12
26
在第一个定义中,我使用greater<int>
仍然得到12(最小值)作为输出,而当我使用less<int>
时,我得到26(最大值)。
greater<int>
不应该创建最大堆?
答案 0 :(得分:3)
因为这是他们的工作。 less
和greater
应分别为运算符<
和>
建模,并由priority_queue
用于对其元素进行排序。
它们产生相反的结果,因为它们被定义为这样做(除了相同的元素)。
不应该
greater<int>
创建最大堆?
您错误地将容器的内部表示与top()
成员函数的接口混淆,该接口应该根据比较器产生顶部元素。
答案 1 :(得分:3)
就内部算法本身而言,std::priority_queue
总是创建&#34; max heap&#34;。你只需要教它来比较元素,以便它知道什么&#34; s&#34; max&#34;。
要确定&#34; max heap&#34;的顺序,它使用&#34; less&#34;-style比较谓词:当给出一对(a, b)
时(按特定顺序)谓词应该告诉a
是否小于 b
。通过使用从谓词std::priority_queue
获得的排序信息,将确保更大元素位于堆的顶部。标准std::less
是此类谓词的示例。无论你提供什么谓词,实现都会将它视为一个不那么简单的谓词。
如果你提供一个实现相反比较的谓词(比如std::greater
),你自然会在最上面找到最小元素。基本上,人们可以这样说:std::priority_queue
期望&#34;更少&#34;比较谓词,并通过提供更大的&#34;比较谓词而不是你基本上欺骗队列(以明确定义的方式)。欺骗的主要后果是对你(外部观察者)&#34; max heap&#34;变成了#34; min heap&#34;。
这正是你所观察到的。
答案 2 :(得分:2)
std :: priority_queue是&#34; max heap&#34;。您提供的是一个小于运营商;而顶部的元素是最大的。
在你的第二个例子中,你提供的不是直观的std :: less;你会看到顶部最大的元素。
在你的第一个例子中,你认为一个更大的int是&#34;小于&#34;一个较小的int;和#34;最大&#34;元素基于你的&#34;小于&#34;实际上是最小的int。