默认是大顶堆(最大元素在队首),底层使用std::less比较器;小顶堆需自定义比较器,如std::greater或仿函数,返回true表示第一个参数优先级更低。

默认就是大顶堆,小顶堆得手动改比较器,不是加个参数就能切的。
priority_queue 默认是大顶堆还是小顶堆?
默认是大顶堆(最大元素在队首)。它底层用 std::less 作为比较器,等价于 std::less<int></int>,即 a 为真时认为 <code>a 优先级更低——所以大的数“浮”在上面。
- 这意味着
top()返回的是当前最大值 - 插入
1, 5, 3后,top()是5,不是1 - 别被“queue”字面意思误导,它不按插入顺序排,而是按值大小排
怎么声明一个小顶堆?
必须显式传入比较器类型,不能靠函数参数或构造时传 lambda(C++17 前不支持),最常用写法是用 std::greater:
std::priority_queue<int, std::vector<int>, std::greater<int>> min_heap;
注意三个模板参数缺一不可:
立即学习“C++免费学习笔记(深入)”;
- 第一个是元素类型(
int) - 第二个是容器类型(必须是支持随机访问且有
push_back/pop_back的,std::vector最常用) - 第三个是比较器(
std::greater<int></int>表示a > b时a优先级更低,所以小的在顶)
别写成 priority_queue<int greater>></int> —— 缺少容器类型,编译直接报错。
自定义类型怎么用 priority_queue?
要么重载 operator,要么传自定义比较器。重载 <code> 最简单,但语义要清晰:
struct Node {
int val;
bool operator<(const Node& rhs) const {
return val < rhs.val; // 这会让大 val 在顶 → 大顶堆
}
};
如果想让小 val 在顶,就得反过来写:return val > rhs.val;。容易写反,建议统一用外部比较器:
struct Compare {
bool operator()(const Node& a, const Node& b) const {
return a.val > b.val; // 小顶堆:a 比 b 大,a 优先级更低
}
};
std::priority_queue<Node, std::vector<Node>, Compare> pq;
注意:这个 Compare 的逻辑和 std::greater 一致——返回 true 表示第一个参数“应该排在后面”,不是“谁更大”。这点最容易绕晕。
常见错误和性能注意点
几个高频翻车现场:
- 误以为
priority_queue支持find或遍历访问中间元素 —— 它只保证top()是极值,其余元素无序,不能索引 - 把
std::priority_queue当作可修改堆(比如改某个元素后自动调整)—— 不支持,只能push/pop - 在循环里反复创建临时
priority_queue却没清空,导致内存缓慢增长(尤其在 long-running 服务中) - 用
std::deque替代std::vector作底层容器 —— 不合法,deque不满足RandomAccessContainer要求,编译失败
底层调整复杂度是 O(log n),但每次 top() 是 O(1);如果只是找最小/最大值且不删,用 std::min_element 可能更轻量。










