今天博主继续带来STL源码剖析专栏的第四篇博客了!
今天带来优先队列priority_queue的模拟实现!
话不多说,直接进入我们今天的内容!


前言

那么这里博主先安利一下一些干货满满的专栏啦!

手撕数据结构https://blog.csdn.net/yu_cblog/category_11490888.html?spm=1001.2014.3001.5482这里包含了博主很多的数据结构学习上的总结,每一篇都是超级用心编写的,有兴趣的伙伴们都支持一下吧!
算法专栏https://blog.csdn.net/yu_cblog/category_11464817.html这里是STL源码剖析专栏,这个专栏将会持续更新STL各种容器的模拟实现。

STL源码剖析https://blog.csdn.net/yu_cblog/category_11983210.html?spm=1001.2014.3001.5482


优先队列是什么

优先队列的底层实现就是数据结构的堆。其中,小顶堆可以不断更新数组里的最小值,大顶堆可以不断更新数组里的最大值,push和pop自带排序功能,经常用来解决TopK问题。

如果大家有需要数据结构堆的实现可以通过博主的传送门食用噢~

【堆】数据结构-堆的实现【超详细的数据结构教学】https://blog.csdn.net/Yu_Cblog/article/details/124944614

priority_queue的模拟实现

priority_queue底层是默认适配vector的,并且默认是大顶堆。

MyPriorityQueue.h

namespace yufc {
template<class T, class Container = vector<T>, class Compare = std::less<T>>
//默认是less Compare是一个进行比较的仿函数
//less -- 小堆
class priority_queue {
public:
template<class InputIterator>
priority_queue(InputIterator first, InputIterator last) {
while (first != last) {
//不要直接去push,push调用的是向上调整,会慢很多
//先弄进数组再建堆快一点,用向下调整
_con.push_back(*first);
++first;
}
//建堆
for (int i = ((_con.size() - 1 - 1) / 2); i >= 0; i--) {
adjust_down(i);
}
}
//如果写了这个构造编译器就不会生成其它类型构造了,所以要自己写
priority_queue() {}
void adjust_up(size_t child) {
Compare cmp;
size_t parent = (child - 1) / 2;//找到父亲节点的下标
while (child > 0) { //logn
//if (_con[child] > _con[parent]) {
//if (_con[parent] < _con[child]) {
if (cmp(_con[parent],_con[child])) {
std::swap(_con[child], _con[parent]);
child = parent;
parent = (child - 1) / 2;
}
else break;
}
}
void adjust_down(size_t parent) {
Compare cmp;
size_t child = parent * 2 + 1;
while (child < _con.size()) {
//选出左右孩子中大的那个
if (child + 1 < _con.size() && cmp(_con[child], _con[child + 1])) {
++child;
}
if (cmp(_con[parent], _con[child])) {
std::swap(_con[child], _con[parent]);
parent = child;
child = parent * 2 + 1;
}
else break;//已经调整结束了,不用再调整了
}
}
void push(const T& x) {
_con.push_back(x);
adjust_up(_con.size() - 1);
}
void pop() {
std::swap(_con[0], _con[_con.size() - 1]);
_con.pop_back();
adjust_down(0);
}
const T& top() {
//返回值不允许修改 -- 修改了就不是堆了
return _con[0];
}
bool empty() const {
return _con.empty();
}
size_t size() const {
return _con.size();
}
private:
Container _con;
};
}

测试代码

void test_priority_queue() {
yufc::priority_queue<int,vector<int>,less<int>>pq; //底层是个堆
//默认是大顶堆 -- 大的优先级高
pq.push(3);
pq.push(1);
pq.push(2);
pq.push(5);
pq.push(0);
pq.push(1);
while (!pq.empty()) {
cout << pq.top() << " ";
pq.pop();
}
cout << endl;
int a[] = { 1,3,5,7,9,2,4,6,8,0 };
yufc::priority_queue<int>pq1(a, a + sizeof(a) / sizeof(int));
while (!pq1.empty()) {
cout << pq1.top() << " ";
pq1.pop();
}
cout << endl;
//priority_queue<int>heap(a, a + sizeof(a) / sizeof(int));//这样构造也可以
//如果想控制是小的优先级高呢?
//我们要调整第三个模板参数,如果想传第三个,就必须传第二个
priority_queue<int,vector<int>,greater<int>>heap(a, a + sizeof(a) / sizeof(int));//这样构造也可以
while (!heap.empty()) {
cout << heap.top() << " ";
heap.pop();
}
cout << endl;
}

尾声

看到这里,相信大家对priority_queue的模拟实现已经有一定的了解了!这些容器的模拟实现,是我们掌握STL的开始,后面,博主将会给大家带来map、set、哈希等等STL容器的模拟实现,持续关注,订阅专栏,点赞收藏都是我创作的最大动力。

(转载时请注明作者和出处。未经许可,请勿用于商业用途 )
更多文章请访问我的主页

@背包https://blog.csdn.net/Yu_Cblog?type=blog

STL源码剖析 | priority_queue优先队列底层模拟实现的更多相关文章

  1. STL"源码"剖析-重点知识总结

    STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合 ...

  2. 【转载】STL"源码"剖析-重点知识总结

    原文:STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点 ...

  3. STL"源码"剖析

    STL"源码"剖析-重点知识总结   STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略 ...

  4. 《STL源码剖析》读书笔记

    转载:https://www.cnblogs.com/xiaoyi115/p/3721922.html 直接逼入正题. Standard Template Library简称STL.STL可分为容器( ...

  5. 通读《STL源码剖析》之后的一点读书笔记

    直接逼入正题. Standard Template Library简称STL.STL可分为容器(containers).迭代器(iterators).空间配置器(allocator).配接器(adap ...

  6. (原创滴~)STL源码剖析读书总结1——GP和内存管理

    读完侯捷先生的<STL源码剖析>,感觉真如他本人所说的"庖丁解牛,恢恢乎游刃有余",STL底层的实现一览无余,给人一种自己的C++水平又提升了一个level的幻觉,呵呵 ...

  7. STL源码剖析 迭代器(iterator)概念与编程技法(三)

    1 STL迭代器原理 1.1  迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型,STL设计的精髓在于,把容器(Containers)和算法(Algorithms)分开,而迭代器(i ...

  8. 《STL源码剖析》相关面试题总结

    原文链接:http://www.cnblogs.com/raichen/p/5817158.html 一.STL简介 STL提供六大组件,彼此可以组合套用: 容器容器就是各种数据结构,我就不多说,看看 ...

  9. STL源码剖析之空间配置器

    本文大致对STL中的空间配置器进行一个简单的讲解,由于只是一篇博客类型的文章,无法将源码表现到面面俱到,所以真正感兴趣的码农们可以从源码中或者<STL源码剖析>仔细了解一下. 1,为什么S ...

  10. STL源码剖析之组件

    本篇文章开始,进行STL源码剖析的一些知识点,后续系列笔记全是参照<STL源码剖析>进行学习记录的 STL在现在的大部分项目中,实用性已经没有Boost库好了,毕竟STL中仅仅提供了一些容 ...

随机推荐

  1. LocalDateTime、LocalDate、Date的相互转换

    1==LocalDateTime 转 LocalDate: 直接调用 toLocalDate() 方法: LocalDateTime localDateTime = LocalDateTime.now ...

  2. 报错:for..in loops iterate over the entire prototype chain, which is virtually never what you want.

    for..in loops iterate over the entire prototype chain, which is virtually never what you want. 意思是使用 ...

  3. XSS、CSRF 以及如何防范

  4. [译] kubernetes:kube-scheduler 调度器代码结构概述

    本文翻译自 https://github.com/kubernetes/community/blob/master/contributors/devel/sig-scheduling/scheduli ...

  5. [转帖]Linux nice和renice命令:改变进程优先级

    https://c.biancheng.net/view/1074.html 当 Linux 内核尝试决定哪些运行中的进程可以访问 CPU 时,其中一个需要考虑的因素就是进程优先级的值(也称为 nic ...

  6. ingress nginx 支持的K8S版本以及nginx版本信息

  7. Sonarqube 二进制的安装与简单使用

    Sonarqube 二进制的安装与简单使用 背景 使用容器安装 sonarqube 发现无法使用PG数据库 尝试了很长时间没搞定 想了想还是使用 二进制的方式进行部署吧. 下载 https://bin ...

  8. [转帖]oracle 审计日志清理

    https://www.cnblogs.com/bangchen/p/7268086.html   --进入审计日志目录: cd $ORACLE_BASE/admin/$ORACLE_SID/adum ...

  9. [转帖]使用 EXISTS 代替 IN 和 inner join

      在使用Exists时,如果能正确使用,有时会提高查询速度: 1,使用Exists代替inner join 2,使用Exists代替 in 1,使用Exists代替inner join例子: 在一般 ...

  10. [转帖]一文解决内核是如何给容器中的进程分配CPU资源的?

    https://zhuanlan.zhihu.com/p/615570804   现在很多公司的服务都是跑在容器下,我来问几个容器 CPU 相关的问题,看大家对天天在用的技术是否熟悉. 容器中的核是真 ...