priority_queue默认是大根堆,即top()返回最大元素;底层使用std::less作为比较器,等价于ab;}}。

priority_queue 默认是大根堆还是小根堆
默认是大根堆,即 top() 返回最大元素。底层用 std::less 作为比较器,等价于 a —— 注意:这个“小于”是用来判断「是否应该把 a 放在 b 下方」的逻辑,不是直观的“谁优先级高”。所以当 less 返回 true,说明 a 应该排在 b 后面(即更小),于是更大的元素浮到顶部。
如何定义小根堆(最小堆)
最常用写法是显式传入 std::greater:
std::priority_queue, std::greater > min_heap;
注意模板三个参数顺序不能错:value_type、container_type、compare_type。漏掉中间的 std::vector 会编译失败,因为默认容器只对第一个模板参数生效,不自动推导后续。
常见错误:
立即学习“C++免费学习笔记(深入)”;
- 写成
priority_queue—— 缺少容器类型,报错类似> too few template arguments - 误以为
greater表示“大的优先”,其实它让小的先出队
用 lambda 写自定义比较器时为什么必须用 decltype + function 包装
因为 priority_queue 模板要求比较器类型可默认构造,而 lambda 表达式类型是独有、不可名状的,且带捕获的 lambda 无法默认构造。裸写 lambda 会触发编译错误,例如:
auto cmp = [](int a, int b) { return a > b; };
std::priority_queue, decltype(cmp)> q(cmp); // ✅ 可行,但需传实例
// std::priority_queue, decltype(cmp)> q; // ❌ 报错:no default constructor
更稳妥的做法是用 std::function 或直接写 struct:
struct Compare {
bool operator()(const int& a, const int& b) {
return a > b; // 小根堆
}
};
std::priority_queue, Compare> q;
用 std::function 虽然可行,但有虚调用开销,且必须指定签名:std::function,一般不推荐用于性能敏感场景。
结构体或类元素的自定义排序怎么写
关键点:比较器函数参数类型必须和 value_type 一致,且不能只靠重载 运算符——priority_queue 不自动查找成员运算符,必须显式提供比较逻辑。
例如对 Node 按 cost 升序排列(小根堆):
struct Node {
int id;
int cost;
};
struct CompareNode {
bool operator()(const Node& a, const Node& b) {
return a.cost > b.cost; // 注意:这里用 > 实现 cost 小的优先
}
};
std::priority_queue, CompareNode> pq;
容易踩的坑:
- 写成
a.cost → 结果变成大根堆(和直觉相反) - 参数用值传递(
Node a)→ 触发不必要的拷贝,建议 const 引用 - 比较函数里访问空指针或未初始化字段 → 运行时报错或行为未定义
如果结构体字段多、排序逻辑复杂,建议把比较器单独抽成命名类型,别用临时 lambda,否则调试和复用都困难。









