C++中priority_queue默认为最大堆,基于vector和堆算法实现;最小堆需指定greater比较器;还可用make_heap等底层函数或手动实现堆结构。

在 C++ 中,priority_queue 是标准模板库(STL)提供的容器适配器,底层默认基于 最大堆(max-heap) 实现,使用 std::vector 作为存储结构,并通过 std::make_heap、std::push_heap、std::pop_heap 等算法维护堆性质。你可以直接使用它,也可以手动实现一个最小堆/最大堆来深入理解原理。
这是最常用、最安全的方式,适用于绝大多数场景:
top() 返回最大值)priority_queue<int vector>, greater<int>></int></int>
示例代码:
#include <queue>
#include <iostream>
using namespace std;
int main() {
// 最大堆(默认)
priority_queue<int> maxQ;
maxQ.push(3); maxQ.push(1); maxQ.push(4);
cout << maxQ.top() << endl; // 输出 4
// 最小堆
priority_queue<int, vector<int>, greater<int>> minQ;
minQ.push(3); minQ.push(1); minQ.push(4);
cout << minQ.top() << endl; // 输出 1
}
理解堆本质的关键是掌握「完全二叉树的数组表示」和「上浮(sift-up)/下沉(sift-down)」操作:
立即学习“C++免费学习笔记(深入)”;
i 的节点,左子节点下标 = 2*i + 1,右子节点 = 2*i + 2,父节点 = (i-1)/2
简易最小堆实现(不带泛型,便于理解):
#include <vector>
#include <iostream>
using namespace std;
class MinHeap {
vector<int> heap;
void siftDown(int i) {
int n = heap.size();
while (true) {
int smallest = i;
int left = 2*i + 1, right = 2*i + 2;
if (left < n && heap[left] < heap[smallest]) smallest = left;
if (right < n && heap[right] < heap[smallest]) smallest = right;
if (smallest == i) break;
swap(heap[i], heap[smallest]);
i = smallest;
}
}
void siftUp(int i) {
while (i > 0) {
int parent = (i-1)/2;
if (heap[i] >= heap[parent]) break;
swap(heap[i], heap[parent]);
i = parent;
}
}
public:
void push(int x) {
heap.push_back(x);
siftUp(heap.size()-1);
}
int top() {
return heap.empty() ? -1 : heap[0];
}
void pop() {
if (heap.empty()) return;
heap[0] = heap.back();
heap.pop_back();
if (!heap.empty()) siftDown(0);
}
bool empty() { return heap.empty(); }
};
C++ 提供了原始堆操作函数,可直接在 vector 或数组上构建/维护堆:
make_heap(first, last):将区间转为最大堆push_heap(first, last):把末尾元素加入已建好的堆(调用前需先 push_back)pop_heap(first, last):把堆顶移到末尾,剩余部分仍是堆(调用后需再 pop_back)greater<t>()</t> 作为比较器示例:
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {3, 1, 4, 1, 5};
make_heap(v.begin(), v.end()); // 构建最大堆
cout << v[0] << endl; // 5
v.push_back(2);
push_heap(v.begin(), v.end()); // 插入 2 并调整
cout << v[0] << endl; // 5 还是最大值
pop_heap(v.begin(), v.end()); // 5 移到末尾
v.pop_back(); // 真正删除
cout << v[0] << endl; // 新的最大值
}
初学堆容易踩坑,这些点值得留意:
priority_queue 不支持随机访问或遍历,不能像 vector 那样用下标取中间元素 运算符,或显式传入比较函数对象(如 <code>greater<pair>></pair>)
不复杂但容易忽略。
以上就是如何用c++++实现一个优先队列 priority_queue和堆【数据结构】的详细内容,更多请关注php中文网其它相关文章!
c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号