std::priority_queue默认为最大堆,底层基于std::vector和std::less,top()返回最大元素;最小堆需显式指定std::greater作为比较器;自定义类型需提供可比较性,常见方式为重载operator

std::priority_queue 默认就是最大堆
直接用 std::priority_queue,它底层默认基于 std::vector 和 std::less,所以每次 top() 拿到的是最大元素。不需要额外写比较逻辑就能当最大堆用:
std::priority_queue<int> max_heap; max_heap.push(3); max_heap.push(1); max_heap.push(4); // top() 返回 4
注意:它不支持遍历、不支持修改中间元素、不能直接访问底层容器——这些是故意设计的限制,不是 bug。
要最小堆?显式传 std::greater
最小堆不是“反向”或“取负”,而是换比较器。必须在模板参数里指定,否则编译失败:
std::priority_queue<int, std::vector<int>, std::greater<int>> min_heap; min_heap.push(3); min_heap.push(1); min_heap.push(4); // top() 返回 1
常见错误:只写 std::priority_queue<int std::greater>></int> ——漏掉中间的容器类型 std::vector<int></int>,会报错 template argument deduction/substitution failed。
立即学习“C++免费学习笔记(深入)”;
自定义类型必须提供可比较性
比如结构体 Task,想按 priority 排序,有三种方式:
- 重载
operator(默认按小于排序,所以要让它返回“优先级更高时更小”) - 单独写一个仿函数,比如
struct Compare { bool operator()(const Task& a, const Task& b) { return a.priority > b.priority; } },然后传给第三模板参数 - 用 lambda?不行——
std::priority_queue要求比较器类型在编译期确定,lambda 类型无法直接作为模板实参
最容易踩的坑:以为 operator 返回 true 就是“放前面”,其实 <code>std::priority_queue 的逻辑是“如果 a
性能和底层容器能换吗?能,但别乱动
std::priority_queue 是适配器,第二模板参数可以换容器,比如用 std::deque 替代 std::vector:
std::priority_queue<int, std::deque<int>, std::greater<int>>
但除非你明确需要 deque 的头尾插入特性(实际极少用),否则没必要换——std::vector 在堆操作中局部性更好,push/pop 均摊 O(log n),已经是最优。
真正要注意的是:别试图通过 std::priority_queue 实现“更新某个元素优先级”的操作,它不支持。这种需求得换 std::set 或手写带索引的堆。


















