priority_queue
一、定义
优先队列是一种队首元素总是队列中最大值或最小值的数据结构。优先队列内部基于堆(heap)这个数据结构实现,C++默认使用的是大根堆。堆是一种完全二叉树的结构,因此内部可以使用数组或vector实现。
二、创建、插入、查询、删除操作
创建:默认创建的优先队列的队首元素为最大值
插入:push,插入后维持队首元素为最大值
查询:top,查看第一个元素,返回最大值
删除:pop,删除后维持队首元素为最大值
因此,下面示例代码的输出为:10 9 8 6 4 2
#include <iostream>
#include <queue>
using namespace std;
int main()
{
int arr[6] = { 10, 2, 4, 8, 6, 9 };
priority_queue<int> pq;
for (int i = 0; i < 6; i++) {
pq.push(arr[i]);
}
while (!pq.empty()) {
cout << pq.top() << ' ';
pq.pop();
}
return 0;
}
三、创建队首元素为最小值的优先队列
C++默认使用大根堆创建优先队列,即队首元素为最大值,如果想要创建一个队首元素为最小值的优先队列,要这么做:
priority_queue <int, vector<int>, greater<int>> gq;
int
:表示元素为int类型vector<int>
:表示内部使用vector作为容器greater<int>
:标准库提供的比较器,用于定义优先级规则
四、优先队列的类方法
方法 | 定义 | 时间复杂度 | 空间复杂度 |
---|---|---|---|
priority_queue::empty() | 返回队列是否为空 | O(1) | O(1) |
priority_queue::size() | 返回队列大小 | O(1) | O(1) |
priority_queue::top() | 返回队列中的堆顶元素 | O(1) | O(1) |
priority_queue::push() | 添加元素到队列末尾,内部维护堆结构 | O(logN) | O(1) |
priority_queue::pop() | 删除队列的首元素 | O(logN) | O(1) |
priority_queue::swap() | 交换两个队列的元素,元素类型必须相同,元素个数可以不同 | O(1) | O(N) |
priority_queue::emplace() | 与push类似,在某些构造方式下,更加高效 | O(logN) | O(1) |
五、大根堆数据结构的实现
优先队列内部使用堆结构实现,堆是一个完全二叉树,内部可以使用一个数组进行表示:
- 假设一个节点在数组中的索引为i
- 节点的左孩子索引为2 * i + 1
- 节点的右孩子索引为2 * i + 2
- 节点的父节点索引为(i - 1) / 2
- 往一个堆插入一个节点的操作叫heap_insert
- 删除一个堆节点的操作叫heapify
具体实现参考:一个简单的堆实现