Learning C++ No.18【STL No.8】

引言:

北京时间:2023/3/18/21:47,周末,不摆烂,但是欠钱终于还是遭报应了,导致坐牢7小时(上午3.5,下午3.5),难受,充分意识到行哥是那么的和蔼可亲,励志下次上蛋哥的课可以还清债务(所以下一篇,乃至更多篇博客,都将是关于系统编程的知识);周末时光:昨天12点睡觉,今天7点40起床,然后到9点上课,12:50追一集动漫,1点整睡觉,睡到2点25分起床上第二节课,到6点,下楼丢垃圾,然后洗澡,到7点,开始看最后一节C++的录屏,现在写博客(吃饭都是在上课的时候完成),无论是上午还是下午,牢底坐穿,但是不怕,小强有韧性,记录周末第一天,还行,不怎么摆烂,但是感觉自己似乎也没学什么东西;这篇博客,我们就来学习一下上篇博客谈到的,优先级队列(堆)的实现和反向迭代器等知识。
在这里插入图片描述

自我实现优先级队列(堆)

上篇博客,我们了解到了优先级队列基本使用,就是类似于一个堆的结构(二叉堆),并且大致结构和二叉树是没有什么区别的,所以总的来说,优先级队列有如下几个特点:优先级队列是一个容器适配器,优先级最高的数据是位于堆的顶部(top),并且实现优先级队列,可以使用任意类型的容器(但一般使用vector),了解了这些,此时我们就来正式的自我实现一下优先级队列吧!

结构如图所示:
在这里插入图片描述

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

如下图:
在这里插入图片描述
如上代码,我们可以发现, 在一个堆中插入和删除数据,为了提高效率最终都需要重新建堆才可以,所以此时就涉及到了两个建堆的函数:adjust_up、adjust_down,所以接下来,让我们一起看一下优先级队列中最关键的两个函数,如下代码:
在这里插入图片描述
在写这两个函数的时候,我们可以和上图(堆的结构图)在脑海中想象,然后结合在一起,可以很好的把代码正确的写出来。

搞定了上述优先级队列中的几个函数关键函数和向上建堆、向下建堆的两个函数,此时优先级队列的大致我们就实现了,但是此时可以发现,在上述的代码中,我们默认都是建一个小堆,如果此时我们要建大堆怎么办,虽然此时是可以通过直接将大于改成小于的方式来实现,但是这样并不是很好,所以此时我们引入一个新概念,也就是昨天浅浅的了解了的仿函数概念。

浅谈仿函数

如下图:
在这里插入图片描述
如上图,我们通过函数重载的形式实现了两个模板类(用于比较大小),此时优先级队列就可以通过调用上述的模板类来实现建大堆和建小堆的直接切换,如下代码所示:

在这里插入图片描述
所以,如上图,当我们使用了仿函数之后,我们就可以直接通过更改模板参数的类型来进行仿函数的切换,来进行大堆和小堆的切换,不需要去使用什么函数指针的方法去调用相应的函数来实现,所以仿函数的发明,就是为了可以让一个模板类(运算符重载)直接被另一个模板类的模板参数使用,然后该模板类直接通过使用模板参数来实现相应的类似函数的功能,不需要使用函数指针,进而调用相应的函数;

总:模板的设计真的非常的牛,什么都可以通过模板的形式进行直接传递和使用

优先级队列完整代码如下:

#include<iostream>
#include<queue>
#include<vector>
using namespace std;

//要明白,此时的堆是一个数组(容器适配器默认是vector),就是使用数组的形式,给我们弄成了一个树的结构,就叫堆
namespace wwx
{
	template<class T>
	struct less//小堆仿函数
	{
		bool operator()(const T& x, const T& y)
		{
			return x < y;
		}
	};
	template<class T, class Container = vector<T>>//建大堆,我们用小于
	struct greater//大堆仿函数
	{
		bool operator()(const T& x, const T& y)
		{
			return x > y;
		}
	};
	template<class T, class Container = vector<T>, class Compare = greater<T>>//此时就可以不需要使用函数指针来调用某个函数了,可以直接使用模板类型来调用仿函数
	class priority_queue
	{
	public:
		void adjust_up(int child)
		{
			int parent = (child - 1) / 2;//这边一定要去把堆排序给复习一下(这个是可以自己推出来的)
			while (child > 0)//建大堆,最坏的情况就是当child为根结点的时候(也就是下标为0的时候),当下标为0就可以停下来了(不然它是会自己break出去的)
			{
				Compare com;
				//if (_con[parent] < _con[child])//建大堆
				if (com(_con[parent], _con[child]))//调用仿函数去比较
				{
					std::swap(_con[parent], _con[child]);
					child = parent;//建大堆(孩子结点大,此时就是让孩子变成父亲,然后重复再去寻找它的父结点)
					parent = (child - 1) / 2;//迭代走走
				}
				else
				{
					break;//此时此时只是向上调整,并不是堆排序
				}
			}
		}
		void adjust_down(int parent)//注意,此时是在类和对象中,所以可以直接使用this指针,所以可以直接使用我们的适配器来存储数据
		{
			int child = parent * 2 + 1;//父亲结点是唯一的,但是孩子结点是有两个
			while (child < _con.size())//这个条件不会写,就是把this指针给漏掉了
			{
				Compare com;
				//if (child + 1 < _con.size() && _con[child] < _con[child + 1])//左孩子小于右孩子(但是前提是右孩子存在,因为有的地方右孩子是不存在的),所以又漏了一个条件
				if (child + 1 < _con.size() && com(_con[child], _con[child + 1]))
				//if (child + 1 < _con.size() && Compare()(_con[child], _con[child + 1]))//使用匿名对象的写法
				{
					child += 1;
				}
				//if (_con[parent] < _con[child])//但是这种写法是有一个前提的(那种没有前提的写法要去复习)
				if (com(_con[parent], _con[child]))
				{
					std::swap(_con[parent], _con[child]);
					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];
		}
		size_t size()
		{
			return _con.size();
		}
		bool empty()
		{
			return _con.empty();
		}
	private:
		Container _con;
	};
	void test_priority_queue()
	{
		priority_queue<int> pq;
		pq.push(1);
		pq.push(2);
		pq.push(3);
		pq.push(4);
		pq.push(5);

		while (!pq.empty())
		{
			cout << pq.top() << " ";
			pq.pop();
		}
		cout << endl;
	}
}
int main()
{
	wwx::test_priority_queue();

	return 0;
}

反向迭代器

我们当时在学习list的时候,已经将正向迭代器给实现了,所以现在,我们就来实现一下返向迭代器,区分为(我们认为的反向迭代器和源码中的反向迭代器),如下代码:
在这里插入图片描述
如上图就是我们认为的,反向迭代器和正向迭代器的实现和区别,但是在真正的源码中却不是如上图中一样,而是实现了更高级的写法,如下代码所示:
在这里插入图片描述
通过上述的结构图,实现代码如下:
在这里插入图片描述

总:反向迭代器的源码是非常的高级的

在这里插入图片描述

总结:周末不摆烂,睡觉啦!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

固定资产管理方案:二维码扫扫便知道

用草料可以批量、简单、低成本地制作固定资产二维码标签。 适用于办公设备、车辆、医疗器械、大型生产设备等需要制作一物一码标签的场景。还能配合报修表单、手机端编辑子码功能共同使用&#xff0c;完成对于固定资产的规范化管理&#xff1a; 用二维码管理公司固定资产1、固定…

【Linux】进程等待进程程序替换

进程等待&进程程序替换进程等待进程程序替换通过进程等待和进程程序替换来理解守护进程进程等待 僵尸进程的产生原因是&#xff1a;子进程先于父进程退出&#xff0c;在子进程退出时会给父进程发送SIGCHILD信号&#xff0c;而父进程接收到这个信号后选择不处理&#xff0c;…

2023年MathorCup数学建模赛题浅析

MathorCup俗称妈杯&#xff0c;是除了美赛国赛外参赛人数首屈一指的比赛&#xff0c;而我们的妈杯今天也如期开赛。今年的妈杯难度&#xff0c;至少在我看来应该是2023年截至目前来讲最难的一场比赛。问题的设置、背景的选取等各个方面都吐露着我要难死你们的想法。难度是恒定的…

世纪末的星期

题目 1、世纪末的星期 曾有邪教称1999年12月31日是世界末日。当然该谣言已经不攻自破。 还有人称今后的某个世纪末的12月31日&#xff0c;如果是星期一则会… 有趣的是&#xff0c;任何一个世纪末的年份的12月31日都不可能是星期一!! 于是&#xff0c;“谣言制造商”又修改为星…

cuda ptx 汇编语言示例:读寄存器

编译 , Ampere 显卡&#xff0c;rtx 3060 3070... nvcc -archsm_86 -o hello hello_ptx.cu 或写成Makefile&#xff1a; hello: hello_sm_id.cunvcc -archsm_86 -o $ $^ #nvcc -archsm_86 -o hello hello_sm_id.cu $ 是指目标 $^ 是指第一个依赖 ^^ hello_ptx.cu #…

WinHex安装与使用

目录 下载WinHex 安装WinHex 查看现成的磁盘文件 手动创建磁盘文件 创建磁盘文件 创建分区 安装引导程序 查看磁盘 下载WinHex 下载链接&#xff1a; WinHex: Hex Editor & Disk Editor, Computer Forensics & Data Recovery Software 安装WinHex 1).下载完…

商贸批发进销存管理软件,仓库条码管理,库存管理。采购入库单,供应商档案管理。

公司发生采购业务&#xff0c;就需要对【供应商】档案进行管理。【供应商】档案包括&#xff1a;编号&#xff0c;名称&#xff0c;地址&#xff0c;电话&#xff0c;负责人&#xff0c;等信息。建立好【供应商】档案电脑存档&#xff0c;方便随时查阅&#xff0c;和统计分析。…

MySQL:安装 MySQL、Navicat、使用 Navicat 连接 MySQL

文章目录Day 01&#xff1a;一、概念1. 数据库 DB2. 数据库管理系统 DBMS3. MySQL二、安装 MySQL三、安装 Navicat Premium 16四、使用 Navicat 连接 MySQL注意&#xff1a;Day 01&#xff1a; 一、概念 1. 数据库 DB 数据库&#xff1a;DB (Database) 数据仓库&#xff0c;…

重磅!阿里版本【ChatGPT】开放测评!

前两天突然爆出惊人消息&#xff1a;阿里版ChatGPT开放测评了&#xff01; 在本月初&#xff0c;已经有诸多关于阿里巴巴即将推出类似ChatGPT产品的传闻。 数日前&#xff0c;首批曝光的天猫精灵“鸟鸟分鸟”脱口秀版GPT基于大型模型的“精简版”&#xff0c;凭借其出色的表现吸…

快看这些wireshark 命令,必须得会!

wireshark捕获命令 捕获器表达式语法&#xff1a; 限定词三类 Type&#xff1a;host、net、prot 指出其后数字或名字的意义&#xff08;主机&#xff0c;网段&#xff0c;端口&#xff09; Direction&#xff1a;src、dst 指出传输方向 &#xff08;源 、目的&#xff09; …

最全Linux环境开发——shell编程

Linux下shell编程 一、什么是shell shell是一个用 C 语言编写的程序&#xff0c;它是用户使用 Linux 的桥梁。Shell 既是一种命令语言&#xff0c;又是一种程序设计语言。 shell 本质上是 linux 命令&#xff0c;一条一条命令组合在一起&#xff0c;实现某一个目的&#xff…

Golang每日一练(leetDay0033) 二叉树专题(2)

目录 97. 交错字符串 Interleaving String &#x1f31f;&#x1f31f; 98. 验证二叉搜索树 Validate Binary Search Tree &#x1f31f;&#x1f31f; 99. 恢复二叉搜索树 Recover Binary Search Tree &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &am…

DFIG控制6-c:数字控制延时的分析和补偿

DFIG控制6-c&#xff1a;数字控制延时的分析和补偿 本文基于教程的第6部分。 DFIM Tutorial 6 - Dynamic Analysis of Current Loops in a Wind Turbine based on DFIG 教程提到了这本书&#xff1a; S.-K. Sul, Control of Electric Machine Drive Systems. John Wiley &…

好用的待办事项APP有哪些

你是否有这样的感受&#xff0c;这就是随着生活和工作节奏的加快&#xff0c;自己经常会面临各种各样的待办事项需要去完成&#xff0c;例如会议安排、每天的工作计划、学习任务等等。但是我们的大脑记忆是有限的&#xff0c;难免会出现忘记待办事项的情况&#xff0c;为了更好…

外包干了三年,算是废了...

先说一下自己的情况。大专生&#xff0c;19年通过校招进入湖南某软件公司&#xff0c;干了接近3年的测试&#xff0c;今年年上旬&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01;而我已经在一个企业干了三年&#xff0c…

detr训练自己的数据集

参考链接&#xff1a; https://zhuanlan.zhihu.com/p/490042821?utm_id0 transform结构&#xff1a; 原理&#xff1a;https://blog.csdn.net/weixin_44649780/article/details/126808881?spm1001.2014.3001.5501 图2&#xff1a; DETR使用一个传统的CNN主干来学习一个输入…

Densely Connected Pyramid Dehazing Network

Abstract 提出了一种新的端到端的单幅图像去雾方法&#xff0c;称为稠密连接金字塔去雾网络&#xff08;DCPDN&#xff09;&#xff0c;该方法可以联合学习透射图、大气光照和去雾。通过将大气散射模型直接嵌入到网络中&#xff0c;实现了端到端的学习&#xff0c;从而保证了所…

【使用教程】CANopen一体化伺服电机在汇川H5U PLC上的应用(上)

本文内容主要介绍了立迈胜一体化低压伺服CANopen通信的电机在汇川H5UPLC上的使用&#xff0c;本篇主要讲解环境的搭建以及软件自带的调试功能使电机运动起来。 一、系统构成 本系统主要构成是笔记本电脑、汇川PLC(H5U-1614MTD-A8)、PMM60系列一体化伺服电机(PMM6040B-CANopen)…

Maxon One 春季版本更新动态

2023年3月29日&#xff0c;Maxon&#xff0c;为剪辑师、电影制作人、动态设计师、视觉特效艺术家和各类创作者提供专业软件解决方案的开发商&#xff0c;今天宣布对Maxon One进行全面更新。 Maxon的2023年春季版本在整个产品系列中提供了令人振奋的新功能和工作流程改进&#x…

创略科技联合创始人兼总裁杨辰韵:AIGC、隐私计算赋能数字营销的本质是“以客户为中心”丨数据猿专访...

‍数据智能产业创新服务媒体——聚焦数智 改变商业MarTech概念现身已超十年&#xff0c;伴随着企业数字化转型的大背景&#xff0c;中国MarTech市场也迎来了高速发展。据《2022年中国MarTech市场洞察报告》数据显示&#xff0c;2017-2021年&#xff0c;中国 MarTech产业规模从…
最新文章