【C++】priority_queue模拟实现过程中值得注意的点
👀樊梓慕:个人主页
🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C++》《Linux》《算法》
🌝每一个不曾起舞的日子,都是对生命的辜负
前言
本篇文章旨在记录博主在模拟实现priority_queue适配器中遇到的一些问题,希望与大家共勉。
欢迎大家📂收藏📂以便未来做题时可以快速找到思路,巧妙的方法可以事半功倍。
=========================================================================
GITEE相关代码:🌟fanfei_c的仓库🌟
=========================================================================
1.priority_queue的介绍
- priority_queue顾名思义:『 优先级队列』;
- 人话:堆。
priority_queue就是基于vector容器的堆,所以未来涉及到『 堆的应用』都可以使用priority_queue适配器。
默认为大堆。

同样通过模板参数的方式来决定底层容器和构建小堆。
比如:
- 使用『 vector』作为底层容器,内部构造『 大堆』结构。
priority_queue<int, vector<int>, less<int>> q1;
- 使用『 vector』作为底层容器,内部构造『 小堆』结构。
priority_queue<int, vector<int>, greater<int>> q2;
- 不指定底层容器和内部需要构造的堆结构,采用默认即vector、大堆。
priority_queue<int> q;
比较奇怪的是:
构建大堆要传less,构建小堆要传greater,容易记混。
- 『 大堆』less就是逐渐变小;
- 『 小堆』greater就是逐渐变大。
2.堆的回顾
2.1向上调整算法
向上调整算法的前提是『 祖先是堆』。
以小堆为例:
1.给定向上调整的起点(孩子节点下标),根据起点下标计算双亲节点下标。
孩子节点与双亲结点间的下标关系:
- child=parent*2+1 || child=parent*2+2;
- parent=(child-1)/2;
2.比较孩子节点与双亲节点数值大小,若孩子节点小于于双亲节点,则交换两者,并将孩子节点的下标更新为之前的双亲节点下标,根据最新的孩子节点下标重新计算双亲节点下标,重复这一过程直到孩子节点为根节点。

//堆的向上调整(小堆)
void AdjustUp(vector<int>& v, int child)
{int parent = (child - 1) / 2; //通过child计算parent的下标while (child > 0)//调整到根结点的位置截止{if (v[child] < v[parent])//孩子结点的值小于父结点的值{//将父结点与孩子结点交换swap(v[child], v[parent]);//继续向上进行调整child = parent;parent = (child - 1) / 2;}else{break;}}
}
2.2向下调整算法
向下调整算法的前提是『 左右子树是堆』。
以小堆为例:
1.给定向下调整的起点(双亲节点下标)和节点总数,根据起点下标计算孩子节点下标。
注意:向下调整时,若有两个孩子节点,则需要确保调整的是较小的孩子节点。
2.比较孩子节点与双亲节点数值大小,若孩子节点小于双亲节点,则交换两者,并将双亲节点的下标更新为之前的孩子节点下标,根据最新的双亲节点下标重新计算孩子节点下标,重复这一过程直到孩子节点超出节点总数。

//堆的向下调整(小堆)
void AdjustDown(vector<int>& v, int n, int parent)
{//child记录左右孩子中值较大的孩子的下标int child = 2 * parent + 1;//先默认其左孩子的值较小while (child < n){if (child + 1 < n && v[child+1] < v[child])//右孩子存在并且右孩子比左孩子还小{child = child + 1;//较小的孩子改为右孩子}if (v[child] < v[parent])//左右孩子中较小孩子的值比父结点还小{//将父结点与较小的子结点交换swap(v[child], v[parent]);//继续向下进行调整parent = child;child = 2 * parent + 1;}else{break;}}
}
3.构建大小堆的模板参数问题『仿函数 』
这里同样涉及到模板参数的传递问题。
在学习堆时,我们知道可以通过改变比较方式从而实现建大堆或者建小堆:

但我们不能每次都手动的去改变这个符号从而满足用户需求。
所以这里我们同样可以利用『 仿函数』来解决这一问题。
仿函数是一个类或结构体,它重载了operator()运算符,使其可以像函数一样被调用。
仿函数的实例可以像函数指针一样传递给STL算法或容器的操作,从而实现自定义行为。
如同我们今天的例子,_com是less类的实例对象,less类重载了操作符(),使其类似于函数调用,内部实现比较大小的功能返回布尔值,_com()就是仿函数,该仿函数模拟了函数行为,使if的判断条件为真或假,从而达到我们>、<的目的。
- 函数参数传参是在『 使用时传参』,传递的是『 对象』;
- 模板参数传参是在『 编译时传参』,传递的是『 类型』。
4.模拟实现源码
#pragma oncenamespace F
{//比较方式:减小堆template<class T>class less{public:bool operator()(const T& x, const T& y){return x < y;}};//比较方式:建大堆template<class T>class greater{public:bool operator()(const T& x, const T& y){return x > y;}};template<class T, class Container = std::vector<T>, class Compare = less<T>>class priority_queue{public://向上调整void adjust_up(int child){int parent = (child - 1) / 2;while (child > 0){//通过模板参数Compare确定是否需要交换结点位置if (_com(_con[child],_con[parent])){swap(_con[child], _con[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}}//向下调整void adjust_down(int parent){int child = parent * 2 + 1;while (child < _con.size()){if (child + 1 < _con.size() && _com(_con[child+1],_con[child])){++child;}if (_com(_con[child], _con[parent])){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(){swap(_con[0], _con[_con.size() - 1]);_con.pop_back();adjust_down(0);}const T& top(){return _con[0];}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;//底层容器Compare _com;//比较方式};
}
=========================================================================
如果你对该系列文章有兴趣的话,欢迎持续关注博主动态,博主会持续输出优质内容
🍎博主很需要大家的支持,你的支持是我创作的不竭动力🍎
🌟~ 点赞收藏+关注 ~🌟
=========================================================================
相关文章:
【C++】priority_queue模拟实现过程中值得注意的点
👀樊梓慕:个人主页 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 🌝每一个不曾起舞的日子,都是对生命的辜负 前言 本篇文章旨在记录博主在模…...
Git提交 ssh: connect to host github.com port 22: Connection timed out解决方案
你们好,我是金金金。 场景 之前都是好好的,不知道今天为什么提交代码就这样了 排查 根据英文可以看出,ssh端口号被拒绝了,22号端口不行,那就换一个端口 造成error的原因 ssh端口被拒绝 解决 找到.ssh文件ÿ…...
Java调用WebService接口,SOAP协议HTTP请求返回XML对象
Java调用Web service接口SOAP协议HTTP请求,解析返回的XML字符串: 1. 使用Java的HTTP库发送SOAP请求,并接收返回的响应。 可以使用Java的HttpURLConnection、Apache HttpClient等库。 2. 将返回的响应转换为字符串。 3. 解析XML字符串&…...
Django框架二
一、模型层及ORM 1.模型层定义 负责跟数据库之间进行通信 2.Django配置mysql 安装mysqlclient,mysqlclient版本最好在13.13以上 pip3 install mysqlclient DATABASES {default: {ENGINE: django.db.backends.mysql,NAME: "mysite1",USER:root,PASSWO…...
工业相机与镜头参数及选型
文章目录 1、相机成像系统模型1.1 视场1.2 成像简化模型 2、工业相机参数2.1 分辨率2.2 靶面尺寸2.3 像元尺寸2.4 帧率/行频2.5 像素深度2.6 动态范围2.7 信噪比2.8 曝光时间2.9 相机接口 3、工业镜头参数3.1 焦距3.2 光圈3.3 景深3.4 镜头分辨率3.5 工作距离(Worki…...
VSCode使用Makefile Tools插件开发C/C++程序
提起Makefile,可能有人会觉得它已经过时了,毕竟现在有比它更好的工具,比如CMake,XMake,Meson等等,但是在Linux下很多C/C源码都是直接或者间接使用Makefile文件来编译项目的,可以说Makefile是基石…...
用C语言验证“三门定理”
#include <stdio.h> #include <stdbool.h> #include <stdlib.h> #include <time.h>// 一个源自博弈论的数学游戏问题: // 参赛者会看见三扇门, // 其中一扇门的里面有一辆汽车, // 选中里面是汽车的那扇门࿰…...
计算机网络-分层结构,协议,接口,服务
文章目录 总览为什么要分层怎样分层正式认识分层概念小结 总览 为什么要分层 发送文件前要做的准备工作很多 把这个准备工作分层小问题解决,也就分层解决 怎样分层 每层相互独立,每层做的工作不同 界面自然清晰,层与层之间的接口能够体现…...
前端开发 2: CSS
在前端开发中,CSS(层叠样式表)是一种用于描述网页样式的语言。它控制着网页的布局、颜色、字体等外观效果。在本篇博客中,我将为你介绍 CSS 的基础知识和常用技巧,帮助你更好地掌握前端开发中的样式设计。 CSS 基础知…...
嵌入式-Stm32-江科大基于标准库的GPIO4个小实验
文章目录 一 、硬件介绍二 、实验:LED闪烁、LED流水灯、蜂鸣器提示2.1 需求1:面包板上的LED以1s为周期进行闪烁。亮0.5s,灭0.5s.....2.2 需求2: 8个LED实现流水灯2.3 需求3:蜂鸣器不断地发出滴滴、滴滴.....的提示音。蜂鸣器低电平触发。 三、…...
HackTheBox - Medium - Linux - Noter
Noter Noter 是一种中型 Linux 机器,其特点是利用了 Python Flask 应用程序,该应用程序使用易受远程代码执行影响的“节点”模块。由于“MySQL”守护进程以用户“root”身份运行,因此可以通过利用“MySQL”的用户定义函数来利用它来获得RCE并…...
Uniapp多选Popup(弹出层)
uniapp中多选组件很少,故个人简单开发了一个,可简单使用,也可根据个人需求稍微改进 支持的功能 单选多选(默认)限制选择数量默认选中禁用选项 属性说明 属性默认值说明singlefalsetrue为开启单选,否则为…...
什么是网络安全?网络安全概况
网络安全涉及保护我们的计算机网络、设备和数据免受未经授权的访问或破坏。 这个领域包括多种技术、过程和控制措施,旨在保护网络、设备和数据免受攻击、损害或未授权访问。网络安全涉及多个方面,包括但不限于信息安全、应用程序安全、操作系统安全等 …...
c语言小游戏之扫雷
目录 一:游戏设计理念及思路 二:初步规划的游戏界面 三:开始扫雷游戏的实现 注:1.创建三个文件,test.c用来测试整个游戏的运行,game.c用来实现扫雷游戏的主体,game.h用来函数声明和包含头文…...
如何本地安装Python Flask并结合内网穿透实现远程开发
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
在线App封装技术:HTML5的新生命
HTML5封装的魅力所在HTML5带来了丰富的多媒体功能、地理位置服务、离线存储等特性,使得Web应用的体验更加接近原生App。封装HTML5到App中,可以大大缩短开发周期,降低开发成本,并且一次编写,多平台运行,极大…...
Spring Boot 4.0:构建云原生Java应用的前沿工具
目录 前言 Spring Boot简介 Spring Boot 的新特性 1. 支持JDK 17 2. 集成云原生组件 3. 响应式编程支持 4. 更强大的安全性 5. 更简化的配置 Spring Boot 的应用场景 1. 云原生应用开发 2. 响应式应用程序 3. 安全性要求高的应用 4. JDK 17的应用 总结 作…...
Debian系统写Mysql时中文出现乱码无法定入的问题解决方案
原因是操作系统可能精简安装,没有GBK字符集,只有UTF8在转换或使用的时候有问题。 使用locale -a查看系统支持的字符集。正常的比较全的字符集的操作系统如下: 有问题的操作系统字符集如下: 解决方案: 步骤1&#…...
CPMS靶场练习
关键:找到文件上传点,分析对方验证的手段 首先查看前端发现没有任何上传的位置,找到网站的后台,通过弱口令admin 123456可以进入 通过查看网站内容发现只有文章列表可以进行文件上传;有两个图片上传点 图片验证很严格…...
CTFhub-bak文件
CTFhub-Web-信息泄露-备份文件下载-bak文件 题目信息 解题过程 看到提示说和index.php有关,在url后面加index.php.bak,跳转到http://challenge-7a4da2076cfabae6.sandbox.ctfhub.com:10800/index.php.bak网址,即: 跳转到下载页…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...

