目录
注意:
- 默认情况下priority_queue是大堆。
- 默认情况下priority_queue是以vector作为底层容器
(大多数情况下都是使用vector作为底层容器即可,我们需要变动的只是存储类型、构造堆结构的形式)
方式一:规定的存储类型,默认内部构造大堆结构
- //int类型:
- priority_queue<int> q1;
- //double类型
- priority_queue<double> q2;
方式二:默认内部构造小堆结构
priority_queue<int, vector<int>, greater<int>> q;
templatepriority_queue (InputIterator first, InputIterator last, const Compare& comp = Compare(), const Container& ctnr = Container());
- vector<int> v{ 1,2,3,4,5,6,7,8,9,10 };
- //使用大堆结构
- priority_queue<int> q1(v.begin(), v.end());
- //使用小堆结构
- priority_queue<int, vector<int>, greater<int>> q2(v.begin(), v.end());
| empty | 测试容器是否为空(公共成员函数) |
| size | 返回大小(公共成员函数) |
| top | 访问顶部元素(公共成员功能) |
| push | 插入元素(公共成员函数) |
| emplace | (C++11)构造并插入元素(公共成员函数) |
| pop | 删除顶部元素(公共成员函数) |
| swap | (C++11)交换内容(公共成员函数) |
- #include
- #include
- #include
- using namespace std;
- int main() {
- priority_queue<int> q1;
- for (int i = 0; i < 10; i++)
- {
- q1.push(i);
- }
- //q1:9 8 5 6 7 1 4 0 3 2
-
- vector<int> v{ 10,20,30 };
- priority_queue<int> q2(v.begin(), v.end());
- //q2:30 20 10
-
- q2.swap(q1);
- cout << q1.size() << endl;//输出:3
- cout << q2.size() << endl;//输出:10
- //q1:30 20 10
- //q2:9 8 5 6 7 1 4 0 3 2
-
- while (!q1.empty()) {
- cout << q1.top() << " ";
- q1.pop();
- }
- cout << endl;
- //输出:30 20 10
-
- return 0;
- }
注意,下标计算父子间的关系:
- leftchild = parent * 2 + 1
- rightchild = parent * 2 + 2
- parent = (child - 1) / 2 (因为只会保留整数部分)
此处以小根堆为例;(向上调整算法用于存入数据)。
(父节点与子节点大小的比较,子对父)

(父节点与子节点大小的比较,父对子)

本人的堆的算法博客:
只要知道了堆的向上排序调整算法和向下排序调整算法后,其实prirotiy_queue的模拟实现几乎已经可以说是完成了。
| 成员函数 | 实现方法 |
| push | 利用容量适配器本身的push_back(),并结合堆的向上调整算法。 |
| pop | 根据堆的排序思维,利用swap(),将第一个元素与最后一个元素交换位子(确保中间元素的堆序不被打乱),然后容量适配器本身的pop_back(),再使用堆的向下调整算法。 |
| top | 利用容量适配器本身的front() |
| size | 利用容量适配器本身的size() |
| empty | 利用容量适配器本身的empty() |
难度提升:
priortiy_queue是可以通过容量适配器实现less与gtreater实现,内部堆排序的结构不同。既然需要less与greater,我们也模拟实现一下。
template
, class Compare = less >
- template<class T>
- class less { bool operator()(T& e1, T& e2) { return e1 < e2; } };
- template<class T>
- class greater { bool operator()(T& e1, T& e2) { return e1 > e2; } };
- #include
- #include
- #include
- using namespace std;
- namespace qcr{
-
- template<class T>
- class less { bool operator()(T& e1, T& e2) { return e1 < e2; } };
- template<class T>
- class greater { bool operator()(T& e1, T& e2) { return e1 > e2; } };
-
- template<class T, class Container = std::vector
, class Compare = less> - class priority_queue {
- public:
- priority_queue():_con() {}
- template<class InputIterator>
- priority_queue(InputIterator begin, InputIterator end) : _con(begin, end) {
- //数据的输入
- //while (begin != end) {
- // _con.push_back(*begin);
- // ++begin;
- //}
-
- //数据的大小堆建立
- for (int i = (_con.size() - 1 - 1) >> 1; i >= 0; --i)
- Adjust_down(i);
- }
-
- void Pop() {
- assert(!empty());
-
- swap(_con[0], _con[_con.size() - 1]);
- _con.pop_back();
- Adjust_down(0);
- }
-
- bool empty()const {
- return _con.empty();
- }
-
- size_t size()const {
- return _con.size();
- }
-
- void push(T x) {
- _con.push_back(x);
- Adjust_up(_con.size() - 1);
- }
-
- const T& top()const
- {
- return _con.front();
- }
-
- //向下排序
- void Adjust_down(size_t parent) {
- size_t child = parent * 2 + 1;
- while (child < _con.size()) {
- if (child + 1 < _con.size() && Compare()(_con[child], _con[child + 1]))
- ++child;
- if (Compare()(_con[parent], _con[child])) {
- //将父节点子节点进行调换
- std::swap(_con[parent], _con[child]);
- //更新父、子节点的位置
- parent = child;
- child = parent * 2 + 1;
- }
- else{
- //堆已经建立成功
- break;
- }
-
- }
- }
-
- //向上排序
- void Adjust_up(size_t child) {
- size_t parent = (child - 1) >> 1;
- while (child) {
- if (Compare()(_con[parent], _con[child])) {
- //将父节点子节点进行调换
- std::swap(_con[parent], _con[child]);
- //更新父、子节点的位置
- child = parent;
- parent = (child - 1) >> 1;
- }
- else {
- //堆已经建立成功
- break;
- }
- }
- }
- Container _con;
- };
- }