C++——list

news2025/1/12 10:43:56

作者:几冬雪来

时间:2023年9月24日

内容:C++板块list知识讲解

目录

前言: 

什么是list: 

遍历list: 

insert:

find:

insert与erase:

merge: 

unique: 

remove:

splice: 

list迭代器: 

构造迭代器: 

begin/end: 

operator*: 

operator++: 

operator!=: 

结尾:


前言: 

上几篇博客中,我们讲解了C++博客中vector的知识,并且也了解了很多vector的接口,和其接口在头文件的写法,同时也交代了vector和string的相似和不同之处,对其进行了改进与分析,而今天我们来讲解C++中的另外一个模板——list。

什么是list: 

要学习list就需要先了解list。

list在C++中是一个顺序容器,也是一个双向链表

list里面的许多的接口,在vector和string中也有存在,可以说在list我们已经学习了许多的接口了,但是在list中,它还加入了一些新的接口,这就要等到以后学习的时候慢慢了解了。 

遍历list: 

既然说list中有许多vector和string拥有的接口,那么接下来我们将简单的将list进行一次遍历

书写到这里的时候,我们要注意一个点。

在C++中list遍历的时候有区别于string和vector,在遍历list的时候,我们并不使用下标方括号的遍历方法,因为它不是连续的空间,最好用的方法是迭代器。 

在这里用遍历就是用迭代器进行遍历,又或者可以使用范围for进行遍历,这是因为范围for的底层就是迭代器

在遍历list的时候不使用下标方括号的遍历方法,但是并不是代表不能用,只是在遍历的时候下标方括号的方法效率极低,因此系统不做这个选择。 

insert:

insert在string和vector中均有了解和学习到,它代表的意思是在某个位置插入某一个值或者某一串字符串,而且string和vector接口的写法是一样的。(要reserve情况另说) 

类似上边的代码就是string或者vector中insert的写法

找到这段原代码的起始位置begin,然后加上想插入值的位置就能成功的在这个位置中插入我们想要的值

但是list和vector根string有根本上的区别,list并不能使用这种方法来进行inset的操作。 

从代码的结果可以看出来如果我们使用vector和string中insert的写法来书写list的代码,程序是会报错的。 

还记得我们上面所说的list在C++中是一个顺序容器,也是一个双向链表。它不像string和vector一样,每个空间都是连续的,可以实现开始位置加查找的位置

list是一个双向指针,因此它的空间并不是连续的,所以用string会vector那种找位置的代码,并不能找到我们想要插入值的位置

如果要在第五个位置处加入想要的值,在list中我们就只能依靠一个一个加上去得到后再去insert

出现这种情况的原因是因为,list的迭代器实现和string等有所区别。 

find:

接下来就来讲解list的find接口,这里有人就要问了,在讲解string和vector的时候也有涉及到了find接口

在list板块为什么还要再讲一遍?

这是因为list的find接口相较于前两者有些许的不同。 

从代码来看,list的find接口对比string和vector板块,多了一个end的选取

这就意味着在使用list的find接口的时候,我们可以选择它的区间查找。 

在这里要注意find的一个细节,通常在find选取区间的时候,区间一般都是左闭右开的(类似[begin(),end()))。这是为了在后面如果查找不到的时候返回end使用做铺垫。 

insert与erase:

既然有find就有erase,在讲解string和vector的时候我们又讲过,代码在进行insert扩容的时候,可能会发生迭代器失效的结果

但是list中insert并不会产生迭代器实失效的结果,反倒是在erase的时候,因此底层是双向指针,因此在erase的时候直接删除数据,这里就肯定会有野指针的出现和迭代器问题的发生。 

merge: 

接下来讲解的是list中出现的新的接口

首先就是merge接口,它的作用是将两个链表归并到一起去,但是在实际显示中我们书写代码的时候并不经常用merge。 

然后下来看一看merge代码的书写。 

这段代码就是我们两个链表归并的代码。

merge前后的first和second是可以进行交换的

同时在进行merge归并的时候要注意其中的一个点,那就是两个链表在归并之前必须要先经过sort的操作进行排序后才能执行。 

unique: 

接下来讲解的是list博客的第二个新街口——unique

unique在C++中所代表的意思是去重,简单来说就是去掉链表中相同的数据

那么unique的代码又应该怎么样去书写呢? 

这就是list中的unique接口,它和merge一样,在使用这个接口之前有一个硬性条件,那就是必须要将数据sort排序一次才能正常使用

不过在写语言的时候我们也极少去使用到这一个接口。

remove:

再下来讲解一下list中的remove接口

remove看着像是一个全新的接口,但是从底层看它的原理,它其实就是find和erase接口的一个结合体

也就是说remove接口的作用是找到我们想要删除的值再对其进行删除。 

在这里我们就可以通过remove来删去数据中想删除的值,就如同上面的代码,我们就可以成功的删除4这个值

这里有人就要问,假如这个地方remove的值不存在,那会发生什么呢?这里可以告诉大家,如果要删除的值不存在,那我们的代码则什么都不会做。 

splice: 

再然后就是list中的splice接口

splice的意思是粘接,在C++的list中,我们可以使用它将两个链表进行一个链接,但是这种连接方式有区别于merge

splice接口中,我们可以选择在原链表的某个位置插入我们的另一个链表而不是单纯的进行尾插链表的操作

而且splice转移的位置是它的前面。  

这里就是list中splice中会被使用的3种不同形式的代码

第一种是全部转移,也就是将mylist的链表全部转移到it的前面。第二种是转移某个值,而且第三种则是转移一个区间。 

list迭代器: 

在介绍完了list的作用,list与string和vector的区别,相比较string和vector的接口list又多了哪些接口之后,接下来我们就来讲解list迭代器的实现了

首先要先写list的迭代器就需要将迭代器的底子铺好

一开始需要我们将双向链表中的next,prev和val数据标记好,接下来要去对数据进行一个初始化,初始化在这个地方,next和prev指向为空,val这里就给val的值

再然后因为迭代器需要有一个头结点,因此在私有数据处要有一个头结点

在这里我们链表的迭代器不能使用内置类型的结点的指针,但是结点的指针还是数据基础

构造迭代器: 

首先,迭代器是一个自定义类型,这个自定义类型的成员是一个结点的指针。 

在这个地方我们就使用结点的指针构造出来了一个迭代器,因为一个迭代器里面数据存储的函数一个结点的指针。 

begin/end: 

接下来我们就需要来我们就来写一写在链表中begin和end的使用方法

在这里就先看一下迭代器中begin的代码书写。

这里有人就要问了,这不是迭代器为什么可以返回结点的指针。

这是因为单参数的构造函数支持隐式类型的转换。 

同样的我们的end接口的代码也是这样书写。 

operator*: 

在list的迭代器中,要获取结点中的指针,解引用是必不可少的操作。 

结点默认的解引用是结点,但是在这个地方我们不想要结点,我们需要的是结点中的数据,那么在这个条件下代码有应该怎么去写呢? 

同时要记得加上&符合,这样就不会导致要return的数据丢失结点还在,val也还存在,做到可读可改。 

operator++: 

再接下来讲解的是list中的operator++,为什么要讲解operator++呢,这是因为对比string和vector的++不同

因为链表不是连续的空间,因此就需要我们的++接口来处理这种情况

 

因为在这里我们是迭代器进行++操作,因此它的返回还是迭代器

然后_node->_next则是指向原结点的下一个位置的值。 

operator!=: 

再然后就是operator!=,这个也是会被使用到了,在判断停止条件的时候就会使用到operator!=来进行我们的条件

接下来就来看看operator!=代码是如何书写的。

像这里就是判断结点是否相等,因为是判断结点是否相等。因此这里更合适使用bool来作为返回的判断

同时只是判断两个结点是否相同,因此要对其加入const防止被修改。 

结尾:

到这里我们的list的知识就有了一个初步的了解了,在list迭代器的后面我们将会list中的const迭代器,list的const迭代器相较于我们之前的迭代器,难度有了一个质的提升,希望这篇粗略的博客能帮到各位吧。 

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

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

相关文章

TLS/SSL(十) session缓存、ticket 票据、TLS 1.3的0-RTT

一 TLS优化手段 TLS 为了提升握手速度而提出优化手段,主要是减少TLS握手中RTT消耗的时间关于session cache和session ticket,nginx关于ssl握手的地方都有影子 [指令] https面经 ① session 缓存 resume: 重用,复用 案例: 第二次访问www.baidu.com 说明&#x…

Linux-多路转接-epoll

epoll 接口认识epoll_createepoll_ctlepoll_wait epoll工作原理在内核中创建的数据结构epoll模型的一个完整工作流程 epoll工作模式LT-水平触发ET-边缘触发两种方式的对比 epoll的使用场景对于poll的改进惊群效应什么是惊群效应如何解决惊群效应原子操作/mutex/spinlock如何选择…

数据结构(java)--队列1

一、我们还是依旧引入一个小例子(银行排队): 需要取号排队,服务完下一个 二、队列介绍 1)队列是一个有序列表,可以用数组或是链表来实现 2)遵循先入先出的原则。即:先存入队列的数…

世界前沿技术发展报告2023《世界信息技术发展报告》(三)量子信息技术

(三)量子信息技术 1. 概述2. 量子计算2.1 阿里巴巴达摩院成功研制两比特量子芯片,单比特操控精度超99.97%2.2 加拿大Xanadu公司开发出可编程光量子计算机2.3 美国英伟达公司为经典-量子混合计算推出开发架构2.4 日本国家自然科学研究所开发出…

el-tree实现菜单功能

用到element tree组件&#xff0c;需要了解他的一些方法 <template><div><!-- default-expand-all 默认展开全部数据 --><!-- expand-on-click-node 只有点击箭头才会收缩节点 --><!-- check-on-click-node 点击文本选中 --><!-- show-check…

cadence - 在allegro中出报告(Padstack Usage Report)来辅助制作orcad原理图封装

文章目录 cadence - 在allegro中出报告(Padstack Usage Report)来辅助制作orcad原理图封装概述笔记做PCB封装出报告 - Padstack Usage Report做原理图封装END cadence - 在allegro中出报告(Padstack Usage Report)来辅助制作orcad原理图封装 概述 现在做封装, 还是手工弄. 在…

1 MySQL 高级(进阶) SQL 语句(一)

目录 1 MySQL SQL 语句 1.1SELECT 1.2 DISTINCT 1.3 WHERE 1.4 AND OR 1.5 in 1.6 BETWEEN 2 通配符 ----通常通配符都是跟 LIKE 一起使用的 2.1 LIKE 2.2 ORDER BY 3函数 3.1数学函数 3.2 聚合函数 3.3 字符串函数 4 GROUP BY 4.1 HAVING 5 别名 6 子查询 …

《开发实战》17 | 异步处理好用,但非常容易用错

大多数业务项目都是由同步处理、异步处理和定时任务处理三种模式相辅相成实现的。区别于同步处理&#xff0c;异步处理无需同步等待流程处理完毕&#xff0c;因此适用场景主要包括&#xff1a; 服务于主流程的分支流程。比如&#xff0c;在注册流程中&#xff0c;把数据写入数…

基于微信小程序的健身私教预约系统设计与实现(开题报告+任务书+源码+lw+ppt +部署文档+讲解)

文章目录 前言运行环境说明用户微信小程序端主要功能有&#xff1a;教练微信小程序的主要功能有&#xff1a;管理员的主要功能有&#xff1a;具体实现截图详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考论文参考…

浅谈基于LoRa技术下智能建筑能耗管理系统的分析与设计

安科瑞 华楠 摘要&#xff1a;城市建设步伐加快背景下&#xff0c;对城市建筑能耗管理系统的应用提出更高要求。从当前各类公共建筑物运营情况看&#xff0c;能源消耗问题仍较为突出&#xff0c;传统依托于计算机、测控单元与通讯设备单位工具的系统管理模式&#xff0c;并不能…

会声会影2023mac电脑免费永久版视频编辑软件

会声会影是由Corel公司制作的一款功能强大的视频编辑软件&#xff0c;具有图像抓取和编修功能&#xff0c;可以抓取、转换MV、DV、V8、TV和实时记录抓取画面文件&#xff0c;并提供有超过100种的编制功能与效果&#xff0c;可导出多种常见的视频格式&#xff0c;甚至可以直接制…

调用ecology的webservice创建流程

开发过程 一、用超级管理员账号登录系统。 二、在地址栏为查看接口地址 IP:端口号/services 三、进入WorkflowServicesAPI 四、打开IDEA编译器&#xff0c;创建项目。 五、选择创建webservice客户端 六、进入项目工程后&#xff0c;检查配置是否正确。代码生成的路径&#x…

Oracle数据库故障处理-swap占用较高,AIX内存溢出

1 故障现象 主机hang死&#xff0c;而且使用vmstat命令发现b列产生大量的值 2 故障分析 关于AIX操作系统的参数maxclient%和maxperm%&#xff0c;该参数主要是限制aix filesystem使用或者直接占用os 物理内存的比例。 # vmo -p -o maxclient%20 Modification to restricted t…

STL-常用容器

string容器 string构造函数 string本质&#xff1a;类 string和char*区别&#xff1a; char* 是一个指针 string是一个类&#xff0c;类内部封装了char*&#xff0c;管理这个字符串&#xff0c;是一个char*型的容器。 特点&#xff1a; string类内部封装了很多成员方法 …

C++初始

想要学习了解C&#xff0c;首先需要了解是C是什么&#xff1f;需要对C有一个明确的定位。 这时候很多人都会说C不就是编程语言吗&#xff0c;有啥可了解的。确实C就是一个编程语言&#xff0c;但是我们在学习的时候要将其当成一种工具&#xff0c;而不是一种技术。简单来说C就…

8应用服务与领域服务

本系列包含以下文章&#xff1a; DDD入门DDD概念大白话战略设计代码工程结构请求处理流程聚合根与资源库实体与值对象应用服务与领域服务&#xff08;本文&#xff09;领域事件CQRS 案例项目介绍 # 既然DDD是“领域”驱动&#xff0c;那么我们便不能抛开业务而只讲技术&…

rk3399 linux4.19 ubuntu mpv播放概率性内核崩溃在vop_crtc_atomic_flush

现象&#xff1a;使用 mpv播放视频时&#xff0c;播放一段时间后内核core 环境&#xff1a; linux sdk版本&#xff1a;4.19.172 ubuntu18系统 验证&#xff1a; 1. /etc/mpv/mpv.conf 默认配置voxv 播放一段时间后&#xff0c;内核core 2. /etc/mpv/mpv.conf vogpu播放稳定…

Python 逢七拍手小游戏2.0

"""逢七拍手游戏介绍&#xff1a;逢七拍手游戏的规则是&#xff1a;从1开始顺序数数&#xff0c;数到有7&#xff0c;或者是7的倍数时&#xff0c;就拍一手。例如&#xff1a;7、14、17......70......知识点&#xff1a;1、循环语句for2、嵌套条件语句if/elif/e…

贪心算法-

代码随想录 什么是贪心 贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 这么说有点抽象&#xff0c;来举一个例子&#xff1a; 例如&#xff0c;有一堆钞票&#xff0c;你可以拿走十张&#xff0c;如果想达到最大的金额&#xff0c;你要怎么拿&#xff…

Oracle分区的使用详解:创建、修改和删除分区,处理分区已满或不存在的插入数据,以及分区历史数据与近期数据的操作指南

一、前言 什么是表分区: Oracle的分区是一种将表或索引数据分割为更小、更易管理的部分的技术。它可以提高查询性能、简化维护操作,并提供更好的数据组织和管理。 表分区和表空间的区别和联系: 在Oracle数据库中,表空间(Tablespace)是用于存储表、索引和其他数据库对…