深入理解 C++ STL 优先队列 priority_queue 原理与实现
优先队列(priority_queue)是 C++ 标准模板库(STL)中一个非常实用的容器适配器。它封装了堆(Heap)数据结构的高效性,让你只需几行代码就能管理复杂的优先级逻辑。在算法竞赛、实时交易系统或高并发服务器中,这种能瞬间获取最高优先级元素的能力至关重要。
核心机制:为什么是堆?
优先队列默认基于最大堆实现。你可以把它想象成一棵用数组存储的完全二叉树,父节点的值总是大于或等于子节点。这种结构保证了堆顶元素永远是当前集合中的最大值。
选择 vector 作为底层容器并非偶然。连续内存结构不仅适合堆的随机访问需求,还能带来更好的缓存命中率。动态数组的特性也支持高效的尾部操作,这与堆的插入逻辑完美契合。
虽然头文件是 ,但这并不意味着它是普通的 FIFO 队列。这里的'队列'更多是指接口的一致性——只允许特定端点访问。插入在队尾,但访问和删除始终针对优先级最高的'队首'。
常用操作速查
在实际开发中,你通常只需要关注以下几个核心接口:
初始化与插入
// 默认构造(最大堆)
priority_queue<int> pq;
// 范围初始化
int arr[] = {1, 5, 3};
priority_queue<int> pq2(arr, arr + 3);
插入元素使用 push(),时间复杂度为 O(log n)。每次插入后,堆会自动调整以维持性质。
访问与删除
// 获取堆顶元素(优先级最高)
int topVal = pq.top();
// 移除堆顶元素
pq.pop();
注意,top() 只是查看,不会移除元素;pop() 才是真正删除。这两个操作配合使用,可以安全地遍历整个队列。
状态检查
bool isEmpty = pq.empty();
size_t count = pq.size();
判断空和获取大小都是 O(1) 操作,非常适合循环控制。
如何构建小顶堆?
默认情况下,priority_queue 是大顶堆。如果你需要最小值优先(例如 Dijkstra 算法),可以通过指定比较器来实现:
#include <functional>
// 使用 greater<int> 实现小顶堆
priority_queue<int, vector<int>, greater<int>> minPq;


