【C++】list使用详解

        本篇介绍一下list链表的使用,后续也是会对list进行模拟实现的。list是链表里面的双向链表

1.文档介绍

list - C++ Referenceicon-default.png?t=O83Ahttps://legacy.cplusplus.com/reference/list/list/

list中的接口比较多,此处类似,只需要掌握如何正确的使用,然后再去深入研究背后的原理,已达到可扩展的能力。以下为list中一些常见的重要接口

2.list常见接口

有了string和vector的基础,现在我们对这些接口一看名字就知道作用,所以就不做过多解释。如果不熟悉,建议先看【C++】string类接口使用(万字详解)

2.1 构造和析构

list<int> l1; 
list<int> l2(4, 1);
list<int> l3(++l2.begin(), --l2.end());
list<int> l4 = l2;

析构函数自动调用

2.2 Capacity:

 2.3 Element access:

 2.4 Modifiers:

顺便说一句,emplace_back 和 push_back 功能上是一样的,只有一点区别,在某些场景下会让emplace_back高效一些。

比如下面的场景。

//一个A类
struct A
{
public:A(int a1 = 1, int a2 = 2):_a1(a1),_a2(a2){}
private:int _a1;int _a2;
};

push_back和 emplace_back都可以像下面这样用。

list<A> lt;
//有名对象
A a1(1, 1);
lt.push_back(a1);
//匿名对象
lt.push_back(A(2, 2));
//有名对象
A a1(1, 1);
lt.emplace_back(a1);
//匿名对象
lt.emplace_back(A(2, 2));

但是,emplace_back 支持如下写法。push_back不可以这样写。

lt.emplace_back(2, 2);

上面这种写法就是支持直接传构造A对象的参数,这里不是隐式类型转换。这就是push_back和 emplace_back的最大差别。

2.5 Iterators:

链表的迭代器需要注意的是:不能用下标+[]来遍历了,因为链表的底层是不连续的。

如果不知道这些接口的功能,建议可以先看一下string的使用,里面对文档做了详细介绍。【C++】string类接口使用(万字详解)_c++ string接口支持的操作-CSDN博客

3.迭代器iterator的性质分类

3.1 性质分类

迭代器从性质上可以分为:单向、双向、随机

经典的随机迭代器:vector / string / deque ...

标志:支持++ / -- / + / -

经典的双向迭代器:list / map / set ...

标志:支持++ / -- ,不支持+和-

经典的单向迭代器:forward_list(单向的链表)  / unordered_xxx(哈希) ...

标志:只支持++

3.2 如何看容器的iterator的性质

在文档的 Member types 部分可以看。

上面这个图是list的文档,list的迭代器类型是bidirectional,就是双向的意思

我们再看一下vector的迭代器类型。

vector就是一个random_access随机访问迭代器

在看一个unordered_map。

unordered_map就是一个forward单向迭代器

3.3 iterator性质的影响

迭代器的性质决定可以使用哪些算法,算法对迭代器是有要求的。

算法相关文档:<algorithm> - C++ Reference   使用时要包含头文件 #include<algorithm>

拿里面的sort举例。

sort要求迭代器类型是一个随机迭代器 ,因为sort底层需要支持+和-的操作

再比如说reverse

 要求传的是双向迭代器

但是!不一定只能是双向迭代器,随机迭代器也可以,只要支持++和--就行,但是forward单向迭代器不可以,因为它只支持++,不支持--

再看find

 find要求传InputIterator,这是什么类型?

iterator引申出input和output,这是不存在的迭代器,没有直接对应的类型,只读和只写。 这是比较抽象的两个东西。

总而言之,InputIterator就是可以给单向、双向、随机三类的任意一种类型迭代器

如果说在用算法的时候,给了错误的迭代器,是会直接报错的。

4.list不常见的接口

4.1 list自己的reverse和sort

这个reverse和sort是list自己的接口,不是算法库里面的。

list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
lt.push_back(5);lt.reverse();

 如果是用算法库里面的reverse,就像下面这么写。

reverse(lt.begin(), lt.end());

reverse用哪个都可以。

list<int> lt;
lt.push_back(1);
lt.push_back(4);
lt.push_back(9);
lt.push_back(6);
lt.push_back(3);lt.sort();

 list自己实现sort是因为算法库里面的sort要求传随机迭代器但是list是双向迭代器,list用不了算法库里面的sort。

4.1.1 仿函数

无论是list自己实现的sort还是算法库里面的,默认排升序。我们想实现降序就要用到仿函数

less和greater这样的两个类模板less是升序greater是降序。用法如下。

list<int> lt;
lt.push_back(1);
lt.push_back(4);
lt.push_back(9);
lt.push_back(6);
lt.push_back(3);greater<int> gt; //降序
lt.sort(gt);
less<int> ls;
lt.sort(ls); //升序

这里也可以用匿名对象,如下。

//匿名对象
lt.sort(greater<int>());//降序
lt.sort(less<int>());//升序

4.2 merge 合并

merge功能是合并两个有序链表。

list<int> lt1, lt2;
lt1.push_back(1);
lt1.push_back(4);
lt1.push_back(9);
lt1.push_back(6);lt2.push_back(2);
lt2.push_back(5);
lt2.push_back(3);
lt2.push_back(8);lt1.sort();//排序
lt2.sort();lt1.merge(lt2);//合并

可以看到,合并之后被合并的链表就空了

4.3 unique 去重

unique是给链表去重的,把重复的数去掉,只保留一个,但是也要有序链表

list<int> lt;
//已经有序
lt.push_back(1);
lt.push_back(4);
lt.push_back(4);
lt.push_back(6);
lt.push_back(9);
lt.unique();//去重

4.4 remove和remove_if

 删除链表节点。找到val了就删除,没找到也不会报错。

按要求删除节点,比如说是偶数就删除。这里也是要用到仿函数,我们后续仔细说。

4.5 splice 粘接

其实本质上是转移节点。被转移的节点或者迭代器区间插入在position之前

list<int> mylist1, mylist2;
list<int>::iterator it;for (int i = 1; i <= 4; ++i)mylist1.push_back(i);      // mylist1: 1 2 3 4for (int i = 1; i <= 3; ++i)mylist2.push_back(i * 10); // mylist2: 10 20 30it = mylist1.begin();
++it;                          // points to 2mylist1.splice(it, mylist2);   // mylist1: 1 10 20 30 2 3 4

 splice也可以转移自己的节点给自己。比如说我们要把下面链表的5转移到头节点去。

list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
lt.push_back(5);
lt.push_back(6);
for (auto e : lt)
{cout << e << " ";
}
cout << endl;int x = 0;
cin >> x;
auto it = find(lt.begin(), lt.end(), x);if (it != lt.end())
{lt.splice(lt.begin(), lt, it); //把lt里的it转移到lt的begin前面
}
for (auto e : lt)
{cout << e << " ";
}
cout << endl;

 如果要把5后面的值全部转移到前面去,后面第3和4个参数就是一段迭代器区间

其他代码不变,if里面改变。

if (it != lt.end())
{//把lt里的it后面的全部转移到lt的begin前面lt.splice(lt.begin(), lt, it, lt.end()); 
}

所以,splice可以把一个链表的节点转移到另一个链表,也可以调整当前链表的节点顺序。 

list的使用就介绍这么多,下篇再见~

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

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

相关文章

分布式事务

参考 Seata 详解Mysql分布式事务XA CAP 这个定理的内容是指&#xff1a;在一个分布式系统中、Consistency(一致性)、Availability(可用性)、Partitiontolerance(分区容错性)&#xff0c;三者不可得兼。 一致性&#xff08;C&#xff09; 在分布式系统中的所有数据备份&…

记录elasticsearch-analysis-dynamic-synonym从8.15.0升级到8.16.0所遇到的问题

记录elasticsearch-analysis-dynamic-synonym从8.15.0升级到8.16.0所遇到的问题 一、打包步骤 步骤一、linux系统下执行elasticsearch-module中的build.sh脚本 步骤二、maven环境下elasticsearch-cluster-runner执行maven install命令安装到本地maven仓库。 步骤三、修改版…

【大模型推理加速】KV cache

目录 1. kv cache 原理1.1 Flops 计算公式推导 2. 缺点3. kv cache 优化3.1 L: Layer-Condensed KV Cache , 粒度大&#xff0c;效率高3.1.1 MiniCache3.1.2 PyramidInfer3.1.3 CLA 3.2 H: Retrieval Head,3.2.1 Razor Attention, DuoAttention3.2.2 GQA多个head共享一份KV 3.3…

esp32c3开发板通过micropython的ubluetooth库连蓝牙设备

ESP32-C3开发板是一款高性能、低功耗的微控制器&#xff0c;搭载了Espressif自家的RISC-V处理器。通过MicroPython&#xff0c;一种面向微控制器的精简版Python编程语言&#xff0c;开发者可以轻松地为ESP32-C3编写代码。MicroPython的ubluetooth库使得ESP32-C3能够通过蓝牙与各…

CTF攻防世界小白刷题自学笔记16

1.Broadcast&#xff0c;难度&#xff1a;1&#xff0c;方向&#xff1a;Crypto&#xff08;密码学&#xff09; 题目来源:2019_Redhat 题目描述:粗心的Alice在制作密码的时候&#xff0c;把明文留下来&#xff0c;聪明的你能快速找出来吗&#xff1f; 给一下题目链接&#…

企业供配电及用电一体化微电网能源管理系统

企业能源管理痛点 信息孤岛 1.保护类、监测类、控制类、治理类、重要负荷等子系统多、分散、独立 2.数据异构、融合困难、数据分析困难 3.用户无法通过一套系统完整的了解整个企业的供电、配电、用电情况&#xff1b; 资源浪费 1.服务器资源浪费 2.应用软件浪费 3.数据…

windows实现VNC连接ubuntu22.04服务器

最近弄了一个700块钱的mini主机&#xff0c;刷了ubuntu22.04系统&#xff0c;然后想要在笔记本上通过VNC连接&#xff0c;这样就有了一个linux的开发环境。最后实现的过程为&#xff1a; 安装vnc服务器 安装 VNC 服务器软件&#xff1a; sudo apt update sudo apt install t…

强化学习数学原理学习(四)

前言 今天是时序差分学习 正文 首先,明确一点,时序差分也是无模型的情况下的强化学习方法,TD学习是蒙特卡洛思想和动态编程&#xff08;DP&#xff09;思想的结合。最基础的时序差分学习估计状态值&#xff0c;而后续提出的Sarsa和Q-learning方法则直接对动作值进行估计。 …

【Redis 探秘】Redis 性能优化技巧

&#x1f449;博主介绍&#xff1a; 博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家&#xff0c;WEB架构师&#xff0c;阿里云专家博主&#xff0c;华为云云享专家&#xff0c;51CTO 专家博主 ⛪️ 个人社区&#x…

RTSP播放器EasyPlayer.js播放器在webview环境下,PC和安卓能够正常播放,IOS环境下播放器会黑屏无法播放

流媒体技术分为顺序流式传输和实时流式传输两种。顺序流式传输允许用户在下载的同时观看&#xff0c;而实时流式传输则允许用户实时观看内容。 流媒体播放器负责解码和呈现内容&#xff0c;常见的播放器包括VLC和HTML5播放器等。流媒体技术的应用场景广泛&#xff0c;包括娱乐…

C语言零基础入门

一、输入输出 &#xff08;1&#xff09;scanf scanf 是C语言中的一个标准库函数&#xff0c;用于从标准输入&#xff08;通常是键盘&#xff09;读取数据。scanf 函数定义在 <stdio.h> 头文件中。 #include <stdio.h>int main(void) {//读取整数 int num;print…

经典的网络安全技术

以我的理解&#xff0c;“黑客”大体上应该分为“正”、“邪”两类&#xff0c;正派黑客依靠自己掌握的知识帮助系统管理员找出系统中的漏洞并加以完善&#xff0c;而邪派黑客则是通过各种黑客技能对系统进行攻击、入侵或者做其他一些有害于网络的事情&#xff0c;因为邪派黑客…

D73【 python 接口自动化学习】- python 基础之正则表达式

day73 正则表达式-元字符匹配 学习日期&#xff1a;20241119 学习目标&#xff1a;正则表达式--133 正则表达式-元字符匹配 学习笔记&#xff1a; 元字符匹配 数量匹配 实践操作 总结 字符串的r标记表示&#xff0c;字符串内转移字符无效&#xff0c;作为普通字符使用正则…

实验一 顺序结构程序设计

《大学计算机&#xfe63;C语言版》实验报告 实验名称 实验一 顺序结构程序设计 实验目的 &#xff08;1&#xff09;掌握C语言中常量和变量的概念。 &#xff08;2&#xff09;掌握C语言中常见的数据类型。 &#xff08;3&#xff09;掌握C语言中变量的定义和赋值方法。 …

在Linux上如何利用NTP使客户端和服务端的时间同步

对于服务端 一、先在服务端安装相关配置-----yum install chrony -y-----并启动 二、进入chrony的文件里----在第三行修改为阿里云时间服务地址 三、在服务端重启chrony 四、进行测试------chronyc sources -v 五、进入chrony的文件里添加客户端的ip地址---在第26行&#…

IDEA2023 SpringBoot整合Web开发(二)

一、SpringBoot介绍 由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。SpringBoot提供了一种新的编程范式&#xff0c;可以更加快速便捷…

[C语言]第十三节 指针一基础知识到高级技巧的全景探索

目录 13.1. 内存和地址 13.1.1. 内存和地址 13.2. 指针变量和地址 13.2.1 取地址操作符&#xff08;&&#xff09; 13.1.2 指针变量和解引⽤操作符&#xff08;*&#xff09; 13.1.3 指针变量的⼤⼩ 13.3. 指针变量类型 13.3.1 指针的解引⽤ 13.3.2 指针-整数 13…

hhdb数据库介绍(9-24)

计算节点参数说明 failoverAutoresetslave 参数说明&#xff1a; PropertyValue参数值failoverAutoresetslave是否可见是参数说明故障切换时&#xff0c;是否自动重置主从复制关系默认值falseReload是否生效否 参数设置&#xff1a; <property name"failoverAutor…

基于Java Springboot网络相册系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

未来已来:少儿编程竞赛聚焦物联网,激发创新潜力

随着人工智能与物联网技术&#xff08;IoT&#xff09;的快速发展&#xff0c;少儿编程教育正在迎来新的变革浪潮。近年来&#xff0c;各类少儿编程竞赛纷纷增加了物联网相关主题&#xff0c;要求学生结合编程知识和硬件设备设计智能家居、智慧城市等创新项目。这一趋势不仅丰富…