【C++/STL】优先级队列的介绍与模拟实现仿函数

✨                                                       万物与我皆是自由诗       🌏 

📃个人主页:island1314

🔥个人专栏:C++学习

🚀 欢迎关注:👍点赞 👂🏽留言 😍收藏  💞 💞 💞


目录

🚀前言

一、优先级队列

✨1、什么是优先级队列

✨2、优先级队列使用

二、仿函数

✨1,什么是仿函数 

✨2,仿函数的简单示例

三、优先级队列模拟实现


🚀前言

点击跳转到文章【C++/STL】stack/queue的使用及底层剖析&&双端队列&&容器适配器

前面我们已经学习了list容器的相关知识,本文主要介绍STL中另外两种重要的结构,stack和queue。但是在STL中这两者并没有划分在容器范围内,而是将其称为容器适配器。

注意:使用优先级队列要包含头文件 < queue >

一、优先级队列

✨1、什么是优先级队列

       优先级队列是一种特殊的队列,其中的元素都被赋予了优先级。元素的优先级决定了它们在队列中的顺序。在优先级队列中,元素按照优先级从高到低的顺序出队列。

优先级队列可以通过不同的数据结构来实现,常用的有二叉堆、二叉搜索树和斐波那契堆等。

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

✨2、优先级队列使用

函数声明接口说明
priority_queue()/priority_queue(first,last)构造一个优先级队列
empty( )检测优先级队列是否为空,是返回true,否则返回false
top( )返回优先级队列中最大(最小元素),即堆顶元素
push(x)在优先级队列中插入元素x
pop()删除优先级队列中最大(最小)元素,即堆顶元素

 测试代码如下:

这里的建堆一般有两种方式:
(1) 一种是一个一个push进vector容器再进行向上调整建堆
(2) 另一种是直接用迭代器区间构造直接建堆(推荐用这种)

#include<iostream>
using namespace std;
#include<vector>
#include <queue>
#include <functional> // greater算法的头文件
void TestPriorityQueue()
{// 默认情况下,创建的是大堆vector<int> v = { 3,2,7,6,0,4,1,9,8,5 };priority_queue<int> q1; //使用范围for入队列for (auto e : v)q1.push(e);while (!q1.empty()){cout << q1.top() << " ";q1.pop();}cout << endl;// 建小堆,将第三个模板参数换成greater比较方式//迭代器区间构造,直接建堆priority_queue<int, vector<int>, greater<int>> q2(v.begin(), v.end());while (!q2.empty()){cout << q2.top() << " ";q2.pop();}
}

注意:优先级队列默认的大堆,降序排列,如果要升序,就要换仿函数。下图中第三个模板参数就是传仿函数。

使用算法库里的 less 和 greater 算法,需要包含头文件< functional >

二、仿函数

✨1,什么是仿函数 

仿函数也叫函数对象,是一个重载了 运算符operator() 的类或结构体,可以使得类的对象像函数一样使用,通过重载函数调用运算符,仿函数可以实现自定义的操作行为。

✨2,仿函数的简单示例

operator()并没有参数的个数和返回值,所以使用是十分灵活的

💞样例1:

// 仿函数/函数对象:重载了oparator()的类,类的对象可以像函数一样使用
// operator()特点,参数个数和返回值根据需求确定,不固定,很多样化
class Func
{
public://void operator()() //()函数调用参数列表括号运算//{//	cout << "Func调用" << endl;//}void operator()(int n = 1) //有参{while (n--){cout << "Func调用" << endl;}}
};int main()
{Func f1;f1();//使得对象像函数一样使用f1.operator()(); //显示调用cout << endl;Func f2;f2(3);return 0;
}

💞样例2:模拟实现求平方的功能

// 定义仿函数类
struct Square {int operator()(int a) const {return a * a;}
};int main()     
{Square square;  // 创建仿函数对象int result = square(5);  // 调用仿函数return 0;
}

通过仿函数,我们可以实现更灵活和自定义的操作行为,并且可以与STL算法等标准库函数配合使用,提高代码的可读性和可维护性。

三、优先级队列模拟实现

     优先级队列模拟实现和队列类似,所不同的是每次插入数据后都会使用算法将队列中的数据调整为一个堆,每次删除也是删除堆顶元素,然后将剩余的元素再次调整为一个堆,这样每次堆顶的元素就是所有数据中优先级最高的那一个了,

#pragma once
#include<vector>
#include<functional>namespace qian
{template<class T>struct less{bool operator()(const T& left, const T& right){return left < right;}};template<class T>struct greater{bool operator()(const T& left, const T& right){return left > right;}};template <class T, class Container = std::vector<T>, class Compare = less<T> >class priority_queue{public:priority_queue() //= default;:c(){}template <class InputIterator>priority_queue(InputIterator first, InputIterator last)//:c(first,last) //和下面的一样,都是将数据输入c中{while (first != last){c.push_back(*first);++first;}for (int i = c.size() / 2 - 1; i >= 0; i--) {AdjustDown(i);}}bool empty() const{return c.empty();}size_t size() const{return c.size();}const T& top() const{return c[0]; //上下一样的//return c.front();}void AdjustUp(int child){int parent = (child - 1) >> 1;while (child > 0){if (comp(c[parent], c[child])){std::swap(c[parent], c[child]);child = parent;parent = (child - 1) >> 1;}else break;}}void AdjustDown(int parent){int child = parent * 2 + 1;while (child < c.size()){if (child + 1 < c.size() && comp(c[child], c[child + 1])){ ++child;}if (comp(c[parent], c[child])){std::swap(c[parent], c[child]);parent = child;child = parent * 2 + 1;}else break;}}void push(const T& x){c.push_back(x);AdjustUp(c.size() - 1);}void pop(){if (empty()) return;std::swap(c.front(), c.back());c.pop_back();AdjustDown(0);}private:Container c;Compare comp;};};

测试代码如下:

void test_priority_queue()
{int a[] = { 2,1,7,6,0,4,3,9,8,5 };// 默认是大堆qian::priority_queue<int> q1(a, a+sizeof(a)/sizeof(int));// 小堆qian::priority_queue<int, vector<int>, qian::greater<int>> q2(a, a + sizeof(a) / sizeof(int));cout << "大堆:" << " ";while (!q1.empty()){cout << q1.top() << " ";q1.pop();}cout << endl;cout << "小堆:" << " ";while (!q2.empty()){cout << q2.top() << " ";q2.pop();}cout << endl;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/42010.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于string的‘\0‘与string,vector构造特点加部分特别知识点的讨论

目录 前言&#xff1a; 问题一&#xff1a;关于string的\0问题讨论 问题二&#xff1a;C标准库中的string内存是分配在堆上面吗&#xff1f; 问题三&#xff1a;string与vector的capacity大小设计的特点 问题四&#xff1a;string的流提取问题 问题五&#xff1a;迭代器失…

04.ffmpeg打印音视频媒体信息

目录 1、相关头文件 2、相关结构体 3、相关函数 4、函数详解 5、源码附上 1、相关头文件 #include <libavformat/avformat.h> 包含格式相关的函数和数据结构 #include <libavutil/avutil.h> 包含一些通用实用函数 2、相关结构体 AV…

【PWN · ret2syscall | GoPwn】[2024CISCN · 华中赛区]go_note

一道GoPwn&#xff0c;此外便是ret2syscall的利用。然而过程有不小的曲折&#xff0c;参考 返璞归真 师傅的wp&#xff0c;堪堪完成了复现。复现过程中&#xff0c;师傅也灰常热情回答我菜菜的疑问&#xff0c;感谢&#xff01;2024全国大学生信息安全竞赛&#xff08;ciscn&am…

RabbitMQ快速入门 - 图像化界面的简单操作

目录 1、RabbitMQ的安装 2、RabbitMQ基本介绍 3、简单案例 4、数据隔离 1、RabbitMQ的安装 官网链接&#xff1a;rabbitmq官网 &#xff08;官网很详细&#xff0c;也可以在官网学习啦~&#xff09; 基础入门&#xff1a;自主学习&#xff1a;最新版本&#xff1a;安装我…

缓存-缓存的使用与基本详解

1.缓存使用 为了系统性能的提升&#xff0c;我们一般都会将部分数据放入缓存中&#xff0c;加速访问。而db承担数据落盘工作。 哪些数据适合放入缓存&#xff1f; 即时性、数据一致性要求不高的访问量大且更新频率不高的数据&#xff08;读多&#xff0c;写少&#xff09; …

如何配置 PostgreSQL 以实现高可用性和故障转移?

文章目录 一、高可用性和故障转移的概念&#xff08;一&#xff09;数据复制&#xff08;二&#xff09;监控和检测&#xff08;三&#xff09;快速切换 二、实现高可用性和故障转移的技术方案&#xff08;一&#xff09;流复制&#xff08;Streaming Replication&#xff09;&…

轻松创建对象——简单工厂模式(Java实现)

1. 引言 大家好&#xff0c;又见面了&#xff01;在上一篇文章中&#xff0c;我们通过Python示例介绍了简单工厂模式&#xff0c;今天&#xff0c;我们继续深入这个话题&#xff0c;用Java来实现简单工厂模式。 2. 什么是简单工厂模式 简单工厂模式&#xff08;Simple Facto…

idea部署war包成功,但是接口404

场景 项目结构 xxx-xxx-app xxx-xxx-service xxx-xxx-webappapp/webapp依赖service&#xff0c;service中写了各种api&#xff0c;先别管它合不合理&#xff0c;正式环境用webapp发布。 本地配置tomcat启动&#xff0c;但是发现每次部署成功&#xff0c;但是service中的接口…

【TB作品】脉搏测量,ATMEGA8单片机,Proteus仿真,ATmega8控制脉搏测量与显示系统

硬件组成&#xff1a; LCD1602脉搏测量电路&#xff08;带灯&#xff09;蜂鸣器报警按键设置AT24C02 功能&#xff1a; &#xff08;1&#xff09;LCD1602主页显示脉搏、报警上限、报警下限&#xff1b; &#xff08;2&#xff09;五个按键&#xff1a;按键1&#xff1a;切换设…

baomidou多数据源切换注解@DS没有效果

baomidou多数据源切换注解DS没有效果 <dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.1.1</version> </dependency> ##原因 方法上有Transaction…

Docker学习笔记(二)镜像、容器、仓库相关命令操作

一、docker镜像操作 列出镜像列表 我们可以使用 docker images 来列出本地主机上的镜像。 各个选项说明: REPOSITORY&#xff1a;表示镜像的仓库源 TAG&#xff1a;镜像的标签 IMAGE ID&#xff1a;镜像ID CREATED&#xff1a;镜像创建时间 SIZE&#xff1a;镜像大小 查…

昇思25天学习打卡营第9天|静态图模式的深度剖析与应用指南

目录 背景介绍 动态图模式 静态图模式 静态图模式的使用场景 静态图模式开启方式 基于装饰器的开启方式 基于context的开启方式 静态图的语法约束 JitConfig配置选项 静态图高级编程技巧 背景介绍 AI 编译框架主要包含两种运行模式&#xff0c;即动态图模式与静态图模…

19C 单机文件系统安装文档

准备工作 1)查看系统版本、内核参数 more /etc/redhat-release more /etc/redflag-releaseuname -a2)查看当前系统是否配置了HugePages。在下面的查询中&#xff0c;HugePages的几个相关值都为0&#xff0c;表明当前未配值HugePages&#xff0c;其次可以看到该版本的大页大小为…

Java之网络面试经典题(一)

目录 ​编辑 一.Session和cookie Cookie Session 二.HTTP和HTTPS的区别 三.浅谈HTTPS为什么是安全的&#xff1f; 四.TCP和UDP 五.GET和Post的区别 六.forward 和 redirect 的区别&#xff1f; 本专栏全是博主自己收集的面试题&#xff0c;仅可参考&#xff0c;不能相…

转发服务器实验

首先先克隆一个虚拟机并完成ip地址的修改 nmcli connection modify ens160 ipv4.addresses 192.168.209.128/24 nmcli connection modify ens160 ipv4.method manual nmcli connection modify ens160 connection.autoconnect yes nmcli connection up ens160 nmcli connection…

强化学习编程实战-1-一个及其简单的强化学习实例(多臂赌博机)

1.1 多臂赌博机 一台拥有K个臂的机器&#xff0c;玩家每次可以摇动K个臂中的一个&#xff0c;摇动后&#xff0c;会吐出数量不等的金币&#xff0c;吐出金币的数量服从一定的概率分布&#xff0c;而且不同臂的概率分布不同。 多臂赌博机的问题是&#xff1a;假设玩家共有N次摇地…

WPF中Background=“{x:Null}“ 和 Transparent

WPF中关于背景透明和背景无 此时&#xff0c;我代码中是写的有有个控件&#xff0c;一个Border &#xff0c;一个TextBox &#xff0c;范围都是全屏这么大&#xff0c;可以输入TextBox 因为&#xff0c;当border没有设置背景的时候&#xff0c;实际上是&#xff1a; <Borde…

尚庭公寓——数据库设计

1. 数据的关系 一对一&#xff0c;一对多&#xff08;多对一&#xff09;&#xff0c;多对多 2. 实体关系模型 实体关系模型常用ER图&#xff08;enity relationship graph&#xff09;表示&#xff1b; 矩形表示实体&#xff08;类似Java中的对象&#xff0c;如学生就是一…

NoSQL 之 Redis 配置与常用命令

一、关系型数据库与非关系型数据库 1、数据库概述 &#xff08;1&#xff09;关系型数据库 关系型数据库是一个结构化的数据库&#xff0c;创建在关系模型&#xff08;二维表格模型&#xff09;基础上&#xff0c;一般面向于记 录。 SQL 语句&#xff08;标准数据查询语言&am…

在5G/6G应用中实现高性能放大器的建模挑战

来源&#xff1a;Modelling Challenges for Enabling High Performance Amplifiers in 5G/6G Applications {第28届“集成电路和系统的混合设计”(Mixed Design of Integrated Circuits and Systems)国际会议论文集&#xff0c;2021年6月24日至26日&#xff0c;波兰洛迪} 本文讨…