先说大根堆

priority_queue<int> pq; // 默认大根堆

等价于priority_queue<int, vector<int>, less<int>> pq; // 显式大根堆

小根堆

auto cmp = [](const pair<int,int>& a, const pair<int,int>& b) {
    return a.second > b.second;
};

priority_queue<pair<int,int>, vector<pair<int,int>>, decltype(cmp)> pq(cmp);
//你会发现小根堆里cmp的形参带着const和&,以下是解释

这里的 const & 版本是 最推荐的写法,原因有两点:

  1. priority_queue 在比较元素时不会修改元素,所以参数应当是 只读引用const&)。

  2. 传引用避免了拷贝 pair,效率更高(特别是元素类型比较大时)。

常用堆函数

  • push(x) / emplace(...) —— 插入元素,O(log n)

  • pop() —— 删除堆顶,O(log n)

  • top() —— 取堆顶元素(大根堆最大 / 小根堆最小),O(1)

  • empty() —— 是否为空

  • size() —— 元素数量

下面说说less和greater比较器

这两个是 STL 里最常用的比较器(比较函数对象),你会在 sortpriority_queueset/map 等地方经常看到。我们来详细讲:


1. 它们是什么?

在头文件 <functional> 里,C++ 定义了很多函数对象模板,其中最常见的两个是:


template <class T> struct less { bool operator()(const T& a, const T& b) const { return a < b; // 用 < 比较 } }; template <class T> struct greater { bool operator()(const T& a, const T& b) const { return a > b; // 用 > 比较 } };

也就是说:

  • less<T> 是“a < b”判断器

  • greater<T> 是“a > b”判断器
    它们本质上就是一个函数对象(functor),可以当成函数用。


2. 在排序里的意义

std::sort 默认升序,因为默认比较器是 less<T>


vector<int> v = {3, 1, 4, 1, 5}; sort(v.begin(), v.end()); // 默认用 less<int>,升序 sort(v.begin(), v.end(), less<int>()); // 显式写法 sort(v.begin(), v.end(), greater<int>()); // 降序

输出:


升序: 1 1 3 4 5 降序: 5 4 3 1 1


3. 在堆里的意义

  • priority_queue<int> 默认用 less<int>,是大根堆(最大值在 top)。

  • 如果改成 greater<int>,就是小根堆(最小值在 top)。


priority_queue<int, vector<int>, less<int>> maxHeap; // 大根堆 priority_queue<int, vector<int>, greater<int>> minHeap; // 小根堆

C++ 的堆(无论是 priority_queue 还是 make_heap 系列)里,堆顶就是“优先级最高的元素”,优先级越高,比较器认为最优,less中a<b认为的是b优,故而less实现的是大根堆,而greater实现小根堆


4. 在关联容器里的意义

  • set / map 默认用 less<T>(升序)。

  • 如果你想让 set 降序排列,可以指定 greater<T>


set<int, less<int>> s1 = {3, 1, 4}; // 默认升序 {1,3,4} set<int, greater<int>> s2 = {3, 1, 4}; // 降序 {4,3,1}


5. 它们的本质

lessgreater 其实就是可复用的比较器模板
你完全可以写成 lambda,比如:


auto cmp1 = [](int a, int b){ return a < b; }; // 等价于 less<int> auto cmp2 = [](int a, int b){ return a > b; }; // 等价于 greater<int>


总结

  • less<T>a < b → 升序 / 大根堆 / 默认规则

  • greater<T>a > b → 降序 / 小根堆

  • 用在 sortpriority_queueset/map 等地方,用来指定元素之间的比较逻辑。

更多推荐