当前位置: 首页 > news >正文

【C++干货铺】优先队列 | 仿函数

=========================================================================

个人主页点击直达:小白不是程序媛

C++系列专栏:C++干货铺

代码仓库:Gitee

========================================================================= 

目录

优先队列(priority_queue )的介绍和使用

priority_queue的介绍

priority_queue的使用

大堆 

小堆

priority_queue的模拟实现

仿函数的介绍和使用

仿函数的介绍 

仿函数的使用


优先队列(priority_queue )的介绍和使用

priority_queue的介绍

1. 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。

2. 此上下文类似于,在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元素)。

3. 优先队列被实现为容器适配器,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从特定容器的“尾部”弹出,其称为优先队列的顶部。

4. 底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭代器访问,并支持以下操作:

  • empty():检测容器是否为空
  • size():返回容器中有效元素个数
  • front():返回容器中第一个元素的引用
  • push_back():在容器尾部插入元素 
  • pop_back():删除容器尾部元素

5. 标准容器类vector和deque满足这些需求。默认情况下,如果没有为特定的priority_queue类实例化指定容器类,则使用vector。

6. 需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数make_heap、push_heap和pop_heap来自动完成此操作 

priority_queue的使用

优先级队列默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以考虑使用priority_queue。

注意:

默认情况下priority_queue是大堆。

函数名称函数作用
priority_queue()构造一个空的优先级队列
empty( )检测优先级队列是否为空,是返回true,否则返回
false
top( ) 返回优先级队列中最大(最小元素),即堆顶元素
push(x)在优先级队列中插入元素x
pop()删除优先级队列中最大(最小)元素,即堆顶元素

大堆 

	priority_queue<int,vector<int>> q1;q1.push(5);q1.push(23);q1.push(45);q1.push(7);q1.push(9);q1.push(2);q1.push(53);q1.push(34);cout << q1.size() << endl;while (!q1.empty()){cout << q1.top() << " ";q1.pop();}

小堆

	priority_queue<int,vector<int>,greater<int>> q1;q1.push(5);q1.push(23);q1.push(45);q1.push(7);q1.push(9);q1.push(2);q1.push(53);q1.push(34);cout << q1.size() << endl;while (!q1.empty()){cout << q1.top() << " ";q1.pop();}

 


priority_queue的模拟实现

通过对priority_queue的底层结构就是堆,因此此处只需对对进行通用的封装即可。 

	template <class T, class Container=vector<T>>class priority_queue{public:void adjust_up(int child){int parent = (child - 1) / 2;while (child > 0){if (_con[parent] < _con[child]){swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}else{break;}}}void push(const T& x){_con.push_back(x);adjust_up(_con.size() - 1);}void adjust_down(int parent)//{size_t child = parent * 2 + 1;//while (child < _con.size()){if (child + 1 < _con.size() &&_con[child] < _con[child + 1]){++child;}if(_con[parent] < _con[child]){swap(_con[parent], _con[child]);parent = child;child = parent * 2 +1 ;}else{break;}}}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;};

但是我们编写完成后发现,只能实现大堆/小堆的一种;实现另一种时候需要自己改变函数中的符号,比较麻烦;在C语言中我们会使用函数指针,回调函数解决此问题;但是函数指针比较难以理解和使用,C++就出现了仿函数。


仿函数的介绍和使用

仿函数的介绍 

仿函数(functor),就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数行为,就是一个仿函数类了。 

有些时候,我们在写代码时会发现,某些功能实现的代码会不断的在不同的成员函数中用到,可又不好将这些代码独立出来成为类的一个成员函数,但又很想复用这些代码。写一个公共的函数是一个解决方法,不过函数用到的一些变量,就可能成为公共的全局变量。而且为了复用这么一片代码,就要单立出一个函数,也不好维护,这时就可以用仿函数了。写一个简单类,除了那些维护一个类的函数成员外,就只是实现一个operator(),在类实例化时,就将要用的,非参数的元素传入类中。这样就免去了对一些公共变量全局化的维护。同时,又可以使那些代码独立出来,以便下次复用。而且,这些仿函数还可以用关联、聚合、依赖的类之间的关系,与用到他们的类组合在一起,这样有利于资源的管理(这点可能是它相对于函数最显著的优点了)。如果再配合上模板技术和policy编程思想,就更是威力无穷了,大家可以慢慢的体会。

仿函数的使用

template <class T>
class functor
{
public :bool operator()(const T& x, const T& y){return x > y;}
};
int main()
{functor<int> com;cout << com(2,3)<< endl;cout << com.operator()(3, 2) << endl;return 0;
}

根据仿函数的功能和特性我们可以配合priority_queue的模板,模拟实现和STL库中的priority_queue。只需要在模板中加入一个比较器,默认缺省为实现大堆,在实例化时候可以选择大小堆这样就可以不用直接修改符号了。

	template <class T, class Container=vector<T>,class Compare=Less<T>>class priority_queue{public:void adjust_up(int child)//{Compare com;int parent = (child - 1) / 2;//while (child > 0){if (com(_con[parent] , _con[child])){swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}else{break;}}}void push(const T& x){_con.push_back(x);adjust_up(_con.size() - 1);}void adjust_down(int parent)//{Compare com;size_t child = parent * 2 + 1;//while (child < _con.size()){if (child + 1 < _con.size() && com(_con[child], _con[child + 1])){++child;}if(com (_con[parent] , _con[child])){swap(_con[parent], _con[child]);parent = child;child = parent * 2 +1 ;}else{break;}}}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;};
//大堆
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;}
};

今天对C++中priority_queue和仿函数的介绍、使用、模拟实现的分享到这就结束了,希望大家读完后有很大的收获,也可以在评论区点评文章中的内容和分享自己的看法。您三连的支持就是我前进的动力,感谢大家的支持!! ! 

相关文章:

【C++干货铺】优先队列 | 仿函数

个人主页点击直达&#xff1a;小白不是程序媛 C系列专栏&#xff1a;C干货铺 代码仓库&#xff1a;Gitee 目录 优先队列&#xff08;priority_queue &#xff09;的介绍和使用 priority_queue的介绍 priority_queue的使用 大堆 小堆 priority_queue的模拟实现 仿…...

突破技术障碍:软件工程师如何应对项目中的难题?

在软件开发项目中&#xff0c;工程师常常会遇到各种技术难题。这些难题可能涉及到复杂的算法、不兼容的系统、难以预见的软件行为&#xff0c;或者其他许多方面。 以下是一些策略和方法&#xff0c;可以帮助软件工程师有效地应对这些挑战&#xff1a; 1、理解问题&#xff1a;…...

Linux(7):Vim 程序编辑器

vi 基本上 vi 共分为三种模式&#xff0c;分别是【一般指令模式】、【编辑模式】与【指令列命令模式】。 这三种模式的作用分别是&#xff1a; 一般指令模式(command mode) 以 vi 打开一个文件就直接进入一般指令模式了(这是默认的模式&#xff0c;也简称为一般模式)。在这个模…...

windows搭建gitlab教程

1.安装gitlab 说明&#xff1a;由于公司都是windows服务器&#xff0c;这里安装以windows为例&#xff0c;先安装一个虚拟机&#xff0c;然后安装一个docker&#xff08;前提条件&#xff09; 1.1搜索镜像 docker search gitlab #搜索所有的docker search gitlab-ce-zh #搜索…...

力扣:单调栈算法思路题

单调栈分为单调递增栈和单调递减栈&#xff0c;通过使用单调栈我们可以访问到最近一个比它大&#xff08;小&#xff09;的元素。 &#x1f34a; 单调递增栈&#xff1a;单调递增栈就是从栈底到栈顶数据是依次递增&#xff0c;通常是寻找某方向第一个比它小的元素。 &#x1f…...

11 月 25 日 ROS 学习笔记——3D 建模与仿真

文章目录 前言一、在 ROS 中自定义机器人的3D模型1. 在 rviz 里查看3D模型2. xacro 二、Gazebo1. urdf 集成 gazebo2. 综合应用1). 运动控制及里程计2). 雷达仿真3). 摄像头信息仿真4). kinect 深度相机仿真5). 点云 前言 本文为11 月 25 日 ROS 学习笔记——3D 建模与仿真&am…...

MidJourney笔记(3)-Prompts

MidJourney的Prompts介绍 MidJourney的Prompts是MidJourney的核心之一,这也是我们后续使用MidJourney过程中最重要的工作内容,根据生成的图片,不断的优化我们的Prompts内容。 那Prompts的中文意思是提示的意思。 Prompts的提示语有很多,最基础的用法就是: /imagine prompt…...

贪心 D. Least Cost Bracket Sequence

Problem - D - Codeforces 题目大意&#xff1a;给一个只包含(&#xff0c;)&#xff0c;?三个字符的字符串。每个?可以转为(或者)&#xff0c;对于第 i i i个?转为(需要花费 a i a_i ai​&#xff0c;转为)需要花费 b i b_i bi​。现在问能否让该字符串转为合法的括号匹配…...

iOS APP包分析工具 | 京东云技术团队

介绍 分享一款用于分析iOSipa包的脚本工具&#xff0c;使用此工具可以自动扫描发现可修复的包体积问题&#xff0c;同时可以生成包体积数据用于查看。这块工具我们团队内部已经使用很长一段时间&#xff0c;希望可以帮助到更多的开发同学更加效率的优化包体积问题。 工具下载…...

在 VSCode 中使用 GDB 进行 C/C++ 程序调试(图文版)

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…...

任意文件读取漏洞理解

任意文件读取漏洞理解 1. 漏洞描述&#xff1a; 任意文件读取漏洞是指攻击者可以利用漏洞读取系统上的任意文件&#xff0c;包括敏感信息的配置文件、用户数据甚至系统文件&#xff0c;从而获取未经授权的访问权限。 2. 漏洞原理&#xff1a; 这种漏洞通常是由程序处理用户输入…...

linux 安装yum

问题1&#xff1a;File "/usr/libexec/urlgrabber-ext-down", line 28 except OSError, e: ^ 问题2&#xff1a;yum File "/usr/bin/yum", line 30 except KeyboardInterrupt, e: ^ vim /usr/…...

数学启发式

学习资料&#xff1a; 优化求解器 | Gurobi 数学启发式算法&#xff1a;参数类型与案例实现 数学启发式算法 | 可行性泵 (Feasibility Pump)算法精讲&#xff1a;一份让您满意的【理论介绍编程实现数值实验】学习笔记(PythonGurobi实现) 大佬到底是大佬&#xff01;这些资料太…...

Win10/Win11 使用Wsl的Ubuntu 子系统搭建CGO环境,相当于Ubuntu下开发。GO环境CGO搭建,支持交叉编译

背景&#xff1a; 之前是使用Mac 开发&#xff0c;最近切换到win11下面。发现使用cgo编译有问题。 下面记载了我的使用方法。 环境&#xff1a; win11&#xff08;win10理论一样&#xff09; win11 安装了wsl2的环境&#xff0c;并且安装了ubuntu系统。 在win11 上面安装了g…...

CSS新特性(2-2)

CSS新特性&#xff08;2-2&#xff09; 前言box相关box-shadow background背景rgba颜色与透明度transform:rotate(Xdeg) 2D旋转transform:tranlate 平移 前言 本文继续讲解CSS3其他的新特性&#xff0c;想看之前新特性点击这里&#xff0c;那么好本文正式开始。 box相关 box…...

为什么,word文件在只读模式下,仍然能编辑?

Word文档设置了只读模式&#xff0c;是可以编辑的&#xff0c;但是当我们进行保存的时候就会发现&#xff0c;word提示需要重命名并选择新路径才能够保存。 这种操作&#xff0c;即使可以编辑文字&#xff0c;但是原文件是不会受到影响的&#xff0c;编辑之后的word文件会保存到…...

29 - 装饰器模式:如何优化电商系统中复杂的商品价格策略?

开始今天的学习之前&#xff0c;我想先请你思考一个问题。假设现在有这样一个需求&#xff0c;让你设计一个装修功能&#xff0c;用户可以动态选择不同的装修功能来装饰自己的房子。例如&#xff0c;水电装修、天花板以及粉刷墙等属于基本功能&#xff0c;而设计窗帘装饰窗户、…...

逆矩阵相关性质与例题

1.方阵的行列式&#xff1a;就是将方阵中的每一个元素转换至行列式中。 1.性质一&#xff1a;转置方阵的行列式等于转置前的行列式。&#xff08;对标性质&#xff1a;行列式与它的转置行列式相等&#xff09; 2.性质二&#xff1a;|ka||a|*k的n次方&#xff0c;n为方阵阶数。 …...

Ruoyi项目传List到后台并使用Excel模板下载数据的方法以及遇到的各种前后端数据交互问题

import { download } from @/utils/requestconst app = createApp(App)// 全局方法挂载 app.config.globalProperties.download = download 首先因为ruoyi-ui中的main.js有配置如上全局注册: 因此只需要在vue中定义一个方法直接使用this.download调用下载即可: (download的3…...

区块链技术将如何影响未来的数字营销?

你是否听腻了区块链和数字营销等流行语&#xff0c;却不明白它们对未来意味着什么&#xff1f;那么&#xff0c;准备好系好安全带吧&#xff0c;因为区块链技术将彻底改变我们对数字营销的看法。从建立消费者信任到提高透明度和效率&#xff0c;其可能性是无限的。 让我们来探…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...