我知道如果我使用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
之前,因此更大的元素放在更小的前面元件?
答案 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;。