今天博主继续带来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. Latex公式排版问题总结

    Latex写博客和论文,因为有模板,所以用起来还是很方便的. 但是在实际使用中,由于论文是双栏的,因此比较长的公式在排版时会比较困难.下面对Latex中的公式排版方法做一些记录. Latex公式排版( ...

  2. vivo悟空活动中台 - 微组件多端探索

    本文首发于 vivo互联网技术 微信公众号 链接: https://mp.weixin.qq.com/s/oGX4XSm8F4fa1ocLdpyqlA作者:悟空中台研发团队 [悟空活动中台]系列往期精 ...

  3. 如何在 Debian 12 上安装 MariaDB

    MariaDB 是一个开源多线程的关系数据库管理系统,是 MySQL 的替代品. MariaDB 是 Debian 中 MySQL 的默认替换方案. 本教程介绍如何在 Debian 12 上安装 Ma ...

  4. RabbitMQ的ack机制

    1.什么是消息确认ACK. 答:如果在处理消息的过程中,消费者的服务器在处理消息的时候出现异常,那么可能这条正在处理的消息就没有完成消息消费,数据就会丢失.为了确保数据不会丢失,RabbitMQ支持消 ...

  5. C++跨DLL内存所有权问题探幽(一)DLL提供的全局单例模式

    最近在开发的时候,特别是遇到关于跨DLL申请对象.指针.内存等问题的时候遇到了这么一个问题. 问题 跨DLL能不能调用到DLL中提供的单例? 问题比较简单,就是我现在有一个进程A,有DLL B DLL ...

  6. Python实现PowerPoint(PPT/PPTX)到PDF的批量转换

    如果需要处理大量的PPT转PDF的工作,一个个打开并另存为PDF是非常费时的做法.我们可以利用Python编程语言的强大的工具来自动化这个过程,使得批量转换变得简单而高效.本文将介绍如何使用Pytho ...

  7. python之单线程、多线程、多进程

    一.基本概念 进程(Process) 是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础. 在当代面向线程设计的计算机结构中,进程是线程的容器.程 ...

  8. 域名解析类型及dig,nslookup进行Dns解析过程查看

    本文为博主原创,未经允许不得转载: 通常我们在windows系统下查看域名是不是可以正常访问,是通过cmd命令打开dos窗口,使用ping 命令来查看域名是不是可以正常访问,使用 ping 命令正常访 ...

  9. Linux telnet安装及端口测试联通性

    安装步骤: 可使用该文中的步骤进行安装,已经过本人验证,是可以安装成功的: https://blog.csdn.net/doubleqinyan/article/details/80492421 安装 ...

  10. [转帖]Linux下清理内存和Cache方法见下文:

    https://www.cnblogs.com/the-tops/p/8798630.html 暂时目前的环境处理方法比较简单: 在root用户下添加计划任务: */10 * * * * sync;e ...