为什么更大的<int>和更少的<int>表现出相反的行为?

时间:2016-10-24 15:11:33

标签: c++ stl

请考虑以下代码,

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>不应该创建最大堆?

3 个答案:

答案 0 :(得分:3)

因为这是他们的工作。 lessgreater应分别为运算符<>建模,并由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。