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

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

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

在这里插入图片描述

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

相关文章:

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

引言&#xff1a; 北京时间&#xff1a;2023/3/18/21:47&#xff0c;周末&#xff0c;不摆烂&#xff0c;但是欠钱终于还是遭报应了&#xff0c;导致坐牢7小时&#xff08;上午3.5&#xff0c;下午3.5&#xff09;&#xff0c;难受&#xff0c;充分意识到行哥是那么的和蔼可亲…...

pytorch搭建ResNet50实现鸟类识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客 &#x1f366; 参考文章地址&#xff1a; 365天深度学习训练营-第J1周&#xff1a;ResNet-50算法实战与解析 &#x1f356; 作者&#xff1a;K同学啊 理论知识储备 深度残差网络ResNet&#xff08;dee…...

Node.js -- npm与包

1.包 Node.js中的第三方模块又叫做包 就像电脑和计算机指的是相同的东西&#xff0c;第三方模块和包指的是同一概念&#xff0c;只不过叫法不同。 包的来源&#xff1a; 包是由第三方或者个人团队开发出来的&#xff0c;免费供个人使用。 国外有一家IT 公司&#xff0c;叫做n…...

二 、Locust自定义用户(场景)

二 、自定义用户&#xff08;场景&#xff09; 一个用户类代表了你系统中的一种用户/场景。当你做一个测试运行时&#xff0c;你指定你想模拟的并发用户的数量&#xff0c;Locust将为每个用户创建一个实例。你可以给这些类/实例添加任何你喜欢的属性&#xff0c;但有一些属性对…...

1~3年的测试工程师薪资陷入了瓶颈期,如何突破自己实现涨薪?

对于技术人员而言&#xff0c;职业规划一般分为两个方向&#xff1a;做技术、做管理。进入软件测试行业的新人都会从最基础的执行开始&#xff0c;然后是基本的功能测试。 随后大家会根据个人职业发展来进一步细化&#xff0c;有的走管理路线&#xff0c;成为主管、经理、项目…...

springboot项目前端ajax 07进阶优化,使用jQuery的ajax

使用官网https://jquery.com/ 在下载那里&#xff0c;选择Download the compressed, production jQuery 3.6.4&#xff08;版本不一样&#xff09;&#xff0c;而后在打开的网页中&#xff0c;选择另存为&#xff0c;就下载好了js文件。 > function doAjax(){ …...

东数西存场景的探索与实践

“东数西算”是通过构建数据中心、云计算、大数据一体化的新型算力网络体系&#xff0c;将东部算力需求有序引导到西部&#xff0c;对优化数据中心建设布局&#xff0c;提升国家整体算力水平&#xff0c;促进绿色发展&#xff0c;扩大有效投资&#xff0c;具有重要意义。 在实…...

[图神经网络]PyTorch简单实现一个GCN

Pytorch自带一个PyG的图神经网络库&#xff0c;和构建卷积神经网络类似。不同于卷积神经网络仅需重构__init__( )和forward( )两个函数&#xff0c;PyTorch必须额外重构propagate( )和message( )函数。 一、环境构建 ①安装torch_geometric包。 pip install torch_geometric …...

Elasticsearch(黑马)

初识elasticsearch ​​. 安装elasticsearch 1.部署单点es 1.1.创建网络 因为我们还需要部署kibana容器&#xff0c;因此需要让es和kibana容器互联。这里先创建一个网络&#xff1a; docker network create es-net 1.2.加载镜像 这里我们采用elasticsearch的7.12.1版本的…...

oracle数据库调整字段类型

oracle数据库更改字段类型比较墨迹&#xff0c;因为如果该字段有值&#xff0c;是不允许直接更改字段类型的。另外oralce不支持在指定的某个字段后面新增一个字段&#xff0c;但是mysql数据可以向指定的字段后面新增一个字段。 mysql向指定字段后面新增一个字段&#xff1a; al…...

面部表情识别2:Pytorch实现表情识别(含表情识别数据集和训练代码)

面部表情识别2&#xff1a;Pytorch实现表情识别(含表情识别数据集和训练代码) 目录 面部表情识别2&#xff1a;Pytorch实现表情识别(含表情识别数据集和训练代码) 1.面部表情识别方法 2.面部表情识别数据集 &#xff08;1&#xff09;表情识别数据集说明 &#xff08;2&…...

赛效:如何在线给图片加水印

学会给图片加水印是一个非常实用的技能&#xff0c;可以让你的图片更具保护性和个性化。说到加水印&#xff0c;很多人不知道怎么操作。其实&#xff0c;给图片加水印非常简单&#xff0c;不用下载任何程序&#xff0c;在线就能完成。今天&#xff0c;我将介绍如何使用改图宝在…...

动力节点杜老师Vue笔记——Vue程序初体验

一、Vue程序初体验 我们可以先不去了解Vue框架的发展历史、Vue框架有什么特点、Vue是谁开发的&#xff0c;这些对我们编写Vue程序起不到太大的作用&#xff0c;更何况现在说了一些特点之后&#xff0c;我们也没有办法彻底理解它&#xff0c;因此我们可以先学会用&#xff0c;使…...

ajax上传图片存入到指定的文件夹并回显

html代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><script src"js/jquery-2.1.0.js"></script> </head> <body> <form…...

cesium加载cesiumlab切的影像切片和标准TMS瓦片的区别

1.加载cesiumlab切的影像 var labImg viewer.scene.imageryLayers.addImageryProvider( new Cesium.UrlTemplateImageryProvider({url:http://192.168.1.25:8080/DOMtms/{z}/{x}/{y}.png,fileExtension : "png"})); 2.标准TMS瓦片 var labImg viewer.scene.im…...

第二周P9-P22

文章目录第三章 系统总线3.1、总线的基本概念一、为什么要用总线二、什么是总线三、总线上信息的传送四、总线结构的计算机举例1、单总线结构框图2、面向CPU的双总线结构框图3、以存储器为中心的双总线结构图3.2、总线的分类1、片内总线2、系统总线3、通信走线3.3、总线特性及性…...

java反射

文章目录何为反射&#xff1f;反射的应用场景了解么&#xff1f;谈谈反射机制的优缺点优点缺点反射实战获取 Class 对象的四种方式1. 知道具体类的情况下可以使用TargetObject.class&#xff1a;2. 通过 Class.forName()传入类的全路径获取&#xff1a;3. 通过对象实例instance…...

307 Temporary Redirect 解决办法(临时重定向)

背景&#xff1a;java后台服务请求python服务端 java服务报错&#xff1a;Unexpected response status&#xff1a;307 python服务端报错&#xff1a;307 Temporary Redirect 解决&#xff1a;查了好久找不到什么原因&#xff0c;请求路径问题 请求url&#xff1a;http//:w…...

SpringBoot案例

SpringBoot案例5&#xff0c;案例5.1 创建工程5.2 代码拷贝5.3 配置文件5.4 静态资源目标 基于SpringBoot的完成SSM整合项目开发 5&#xff0c;案例 SpringBoot 到这就已经学习完毕&#xff0c;接下来我们将学习 SSM 时做的三大框架整合的案例用 SpringBoot 来实现一下。我们完…...

Android 10.0 系统framework发送悬浮通知的流程分析

1.前言 在android10.0rom定制化开发中,在原生系统的systemui中,状态栏通知,和闹钟,wifi等悬浮通知也是很重要的, 悬浮通知也是系统通知的一种,也是在frameworks中发送出来的通知,接下来就分析下10.0中的悬浮通知的发送 流程,然后就可以实现自己自定义悬浮通知的相关功…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...