在构建最小堆时,以下比较器如何工作?

时间:2015-06-11 09:43:38

标签: c++ heap

我知道如果我使用STL构建堆,它会产生一个max_heap。如果我想制作一个min_heap,我将不得不编写自己的自定义比较器。现在,以下比较器,

struct greater1{
  bool operator()(const long& a,const long& b) const{
    return a>b;
  }
};

int main() {
  std::vector<long> humble;
  humble.push_back(15);
  humble.push_back(15);
  humble.push_back(9);
  humble.push_back(25);

  std::make_heap(humble.begin(), humble.end(), greater1());
  while (humble.size()) {
    std::pop_heap(humble.begin(),humble.end(),greater1());
    long min = humble.back();
    humble.pop_back();  
    std::cout << min << std::endl;
  }

  return 0;
}

上面的代码我是从网上得到的。我只有一个疑问。比较器实际上是如何工作的。据我所知,不应该像return a < b那样,因为我们希望最小元素在前面,然后在堆中更大的元素。为什么是return a > b。并不代表if (a>b),那么这将返回true,a将被放入堆中b之前,因此更大的元素放在更小的前面元件?

2 个答案:

答案 0 :(得分:0)

我认为你在比较器语义和堆语义之间的联系中读得太多了。请记住,容器的内部细节和结构是故意从您身上抽象出来的,因此,当您开始尝试根据您认为max_heap的内部结构应该如何理解这一点时,您就会被带走。

在标准库中,默认比较器始终 less-than。如果在特定容器/算法中用于排序的元素之间的关系不是less-than,则容器/算法将足够聪明以进行该转换(在这种情况下,通常的实现,通过简单地传递操作数)订单,如cmp(b,a)!)。但是,从根本上说,它始终以less-than排序开始,因为这是采用的一致惯例。

因此,要反转容器的顺序,您需要使用less-than比较器并将其转换为greater-than比较器,无论容器的实际布局如何, (在你看来)结果是。

此外,顺便说一下,为了回应羊角面包的评论,我会按价值long来实现......事实上,只需使用std::greater而不是重新创建它。 / p>

答案 1 :(得分:0)

标准堆以这样的方式构建:对于每个元素a及其子b,比较cmp(b,a)成立,其中cmp是提供的比较器。请注意,cmp的第一个参数是 child 。 (或者,从内部表示中抽象出来,标准方式是cmp(top, other)对于第一个元素top和任何其他other都是正确的。)

这显然是为了使默认比较器(&#34; less&#34;)构建最大堆。

因此,当提供作为第一个参数时,您需要提供一个要返回true的比较器。对于最小堆,这将是更大的&#39;。