C++优先队列(priority_queue)使用详解
一、容器概述
priority_queue
是C++标准库中的容器适配器,实现基于堆结构的优先队列。元素按优先级顺序出队,默认以降序排列(大顶堆)。
二、模板参数解析
模板声明:
template <class T, class Container = vector<T>, class Compare = less<typename Container::value_type>>
1. 类型参数
T
:存储元素的类型Container
:底层容器类型(必须满足SequenceContainer
要求)Compare
:比较函数对象类型(默认less
)
2. 容器适配器要求
底层容器必须提供以下功能:
front()
push_back()
pop_back()
- 随机访问迭代器(因此
list
不兼容)
3. 有效容器类型
priority_queue<int> // 默认vector
priority_queue<int, deque<int>> // 使用双端队列
priority_queue<int, vector<int>, greater<int>> // 显式指定比较器
三、比较函数解析
1. 比较器类型
比较器 | 优先级规则 | 堆类型 |
---|---|---|
less<T> | 值越大优先级越高 | 大顶堆 |
greater<T> | 值越小优先级越高 | 小顶堆 |
2. 比较器工作原理
// 伪代码示例
if (Compare(element1, element2)) {// 当element1应该排在element2下方时返回true
}
四、常用操作
1. 元素访问
top()
:返回优先级最高的元素(时间复杂度O(1))
2. 容量操作
empty()
:判断队列是否为空size()
:返回元素数量
3. 修改器
push(val)
:插入元素(O(logN))emplace(args)
:原地构造元素pop()
:删除堆顶元素(O(logN))
五、关键特性
- 不提供迭代器访问:只能访问堆顶元素
- 自动排序特性:每次push/pop自动维护堆结构
- 容器限制:底层容器必须支持随机访问和快速尾部操作
六、示例代码分析
1. 默认构造方式
priority_queue<int> pq; // 默认使用vector,大数优先
2. 指定比较器
priority_queue<int, vector<int>, greater<int>> pq; // 小数优先
3. 错误示例
priority_queue<int, list<int>> pq; // 编译错误!list不支持随机访问
七、完整代码回顾
#include <iostream>
#include <queue>
#include <deque>
#include <vector>
#include <list>using namespace std;int main(void) {//priority_queue<int> pqA; // 默认情况(less) 值越大,优先级越大//priority_queue<int, vector<int>, greater<int>> pqA; // 使用vector ,值越小,优先级越大priority_queue<int, deque<int>, greater<int>> pqA; // 使用deque ,值越小,优先级越大//priority_queue<int, list<int>, greater<int>> pqA; // 不能使用list,不兼容pqA.push(1);pqA.push(2);pqA.push(3);pqA.push(4);pqA.push(5);while (!pqA.empty()) {cout << pqA.top() << " ";pqA.pop();}system("pause");return 0;
}
八、运行结果说明
当使用greater<int>
比较器时:
1 2 3 4 5
若使用默认less<int>
:
5 4 3 2 1
九、使用注意事项
- 优先选择
vector
作为底层容器(最佳性能) emplace
比push
更高效(避免拷贝构造)- 自定义类型需要重载比较运算符或提供比较器
- 多线程环境需要自行实现同步机制
十、性能特征
操作 | 时间复杂度 | 说明 |
---|---|---|
push() | O(logN) | 堆结构调整 |
pop() | O(logN) | 堆结构调整 |
top() | O(1) | 直接访问堆顶元素 |
empty() | O(1) | 检查容器是否为空 |