c++快速建堆(内含比较器讲解)
先说大根堆
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 & 版本是 最推荐的写法,原因有两点:
-
priority_queue在比较元素时不会修改元素,所以参数应当是 只读引用(const&)。 -
传引用避免了拷贝 pair,效率更高(特别是元素类型比较大时)。
常用堆函数
-
push(x)/emplace(...)—— 插入元素,O(log n) -
pop()—— 删除堆顶,O(log n) -
top()—— 取堆顶元素(大根堆最大 / 小根堆最小),O(1) -
empty()—— 是否为空 -
size()—— 元素数量
下面说说less和greater比较器
这两个是 STL 里最常用的比较器(比较函数对象),你会在 sort、priority_queue、set/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. 它们的本质
less 和 greater 其实就是可复用的比较器模板。
你完全可以写成 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→ 降序 / 小根堆 -
用在
sort、priority_queue、set/map等地方,用来指定元素之间的比较逻辑。
更多推荐
所有评论(0)