【C++】list使用详解

news2024/11/20 6:29:42

        本篇介绍一下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 4

for (int i = 1; i <= 3; ++i)
    mylist2.push_back(i * 10); // mylist2: 10 20 30

it = mylist1.begin();
++it;                          // points to 2

mylist1.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.coloradmin.cn/o/2243870.html

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

相关文章

([LeetCode仓颉解题报告] 661. 图片平滑器

[LeetCode仓颉解题报告] 661. 图片平滑器 一、 题目1. 题目描述2. 原题链接 二、 解题报告1. 思路分析2. 复杂度分析3. 代码实现 三、 本题小结四、 参考链接 一、 题目 1. 题目描述 2. 原题链接 链接: 661. 图片平滑器 二、 解题报告 1. 思路分析 由于只需要3*39个格子&am…

算法-二叉树(从理论知识到力扣题,递归、迭代。)

二叉树 一、二叉树理论知识1、种类a.满二叉树b.完全二叉树c.二叉搜索树d.平衡二叉搜索树 2、java对于树的理解3、存储a.链式存储&#xff08;常用&#xff09;b.数组存储 4、遍历方式a.深度优先搜索b.广度优先搜索 5、树的定义&#xff08;链式&#xff09; 二、力扣题解写题思…

数字后端零基础入门系列 | Innovus零基础LAB学习Day11(Function ECO流程)

###LAB 20 Engineering Change Orders (ECO) 这个章节的学习目标是学习数字IC后端实现innovus中的一种做function eco的flow。对于初学者&#xff0c;如果前面的lab还没掌握好的&#xff0c;可以直接跳过这节内容。有时间的同学&#xff0c;可以熟悉掌握下这个flow。 数字后端…

打开AI的黑盒子——机器学习可解释性!

2024深度学习发论文&模型涨点之——机器学习可解释性 现在以深度学习为主的方法在各个领域都已经next level了&#xff0c;但是如何解释我们的模型仍然是个难题。为什么得到这样的结果往往和结果本身一样重要。因此&#xff0c;个人觉得Explainable AI (XAI)依然会是近些年…

白蚁自动化监测系统的装置和优势

一、背景 在当今社会&#xff0c;随着科技的飞速发展&#xff0c;智能化、自动化技术在各个领域的应用日益广泛&#xff0c;白蚁自动化监测系统作为一种高效、精准的白蚁防控手段&#xff0c;正逐步成为行业内的主流趋势&#xff0c;既是文物古建水利堤坝等预防性保护的要求&a…

HarmonyOs鸿蒙开发实战(10)=>状态管理-对象数组的属性数据变更刷新UI,基于@Observed 和@ObjectLink装饰器

1.条件:基于HarmonyOs5.0.0版本. 2.功能要求&#xff1a;横向列表中每个景点的名称&#xff08;eg: 第二项 “灵隐寺” &#xff09;, 在通过天气接口拿到对应天气后&#xff0c;拼接到名称后面 > 变成&#xff08;“灵隐寺” 天气&#xff09;&#xff09; 3.老规矩先看…

详细描述一下Elasticsearch搜索的过程?

大家好&#xff0c;我是锋哥。今天分享关于【详细描述一下Elasticsearch搜索的过程&#xff1f;】面试题。希望对大家有帮助&#xff1b; 详细描述一下Elasticsearch搜索的过程&#xff1f; Elasticsearch 的搜索过程是其核心功能之一&#xff0c;允许用户对存储在 Elasticsea…

FPGA理论基础1一一一简单的硬件知识

FPGA理论基础一一一简单的硬件知识 文章目录 FPGA理论基础一一一简单的硬件知识一、BANK1.1、BANK01.2、BANK141.3、MGTBANK二、上电时序三 认识命名规则 一、BANK 7系列的FPGA中&#xff0c;BANK分为HPBank、HRBank、HDBank;但并不是一个FPGA中会同时包含HP/HR/HDBank HP(Hi…

【Mysql】函数---控制流函数

1、if逻辑判断语句 格式 解释 if(expr,v1,v2) 如果表达式expr成立&#xff0c;返回结果v1&#xff0c;否则返回v2 ifnull(v…

【Java企业级开发技术】【MyBatis入门程序】上机实验

Java企业级开发技术-MyBatis入门程序-上机实验 1 实验目的 掌握Mybatis环境配置熟悉Mybatis基本开发流程能够开发简单的入门程序 2 实验内容 创建1个学生(student)表,包括学号(num)&#xff0c;姓名(name)&#xff0c;年龄(age)&#xff0c;通过Mybatis框架实现如下数据库访…

python之sklearn--鸢尾花数据集之数据降维(PCA主成分分析)

python之sklearn–鸢尾花数据集之数据降维(PCA主成分分析) sklearn库&#xff1a;Scikit - learn&#xff08;sklearn&#xff09;是一个用于机器学习的开源 Python 库。它建立在 NumPy、SciPy 和 matplotlib 等其他科学计算库之上&#xff0c;为机器学习的常见任务提供了简单…

已解决-idea创建Maven项目卡死,一动不动

先说原因&#xff1a; idea创建maven项目时要从中央仓库下载archetype-catalog.xml(文件较大&#xff0c;14.8M)导致卡住 所以一种解决方案是&#xff0c;手动将这个文件下载到本地的仓库目录下即可解决 文件下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1…

vulhub之log4j

Apache Log4j Server 反序列化命令执行漏洞(CVE-2017-5645) 漏洞简介 Apache Log4j是一个用于Java的日志记录库,其支持启动远程日志服务器。Apache Log4j 2.8.2之前的2.x版本中存在安全漏洞。攻击者可利用该漏洞执行任意代码。 Apache Log4j 在应用程序中添加日志记录最…

基于Springboot+Vue的农产品销售系统 (含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 这个系…

Ascend C算子性能优化实用技巧05——API使用优化

Ascend C是CANN针对算子开发场景推出的编程语言&#xff0c;原生支持C和C标准规范&#xff0c;兼具开发效率和运行性能。使用Ascend C&#xff0c;开发者可以基于昇腾AI硬件&#xff0c;高效的实现自定义的创新算法。 目前已经有越来越多的开发者使用Ascend C&#xff0c;我们…

矩阵论在深度学习中的应用

摘要&#xff1a; 本文深入探讨了矩阵论在深度学习领域的广泛应用。首先介绍了深度学习中数据表示和模型结构与矩阵的紧密联系&#xff0c;接着详细阐述了矩阵论在神经网络训练算法优化、卷积神经网络&#xff08;CNN&#xff09;、循环神经网络&#xff08;RNN&#xff09;及其…

表格的选择弹窗,选中后返显到表格中

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 表格的下拉框可以直接显示选项&#xff0c;那如果选择框不是下拉的&#xff0c;而是弹窗&#xff0c;那么在表格中如何返显呢&#xff1f; 问题描述 如上图所示&#xff0c;点击表格中的选择&#xf…

HCIP --OSI七层参考模型回顾、TCP/UDP协议复习

目录 一、OSI 二、重要的三个协议报头格式 名词注解 MTU 封装 解封装 PDU ARP DNS TCP/IP与OSI的区别 三、数据包转发过程 四、获取目标ip地址方式 五、获取目标mac地址方式 六、交换机的工作原理 七、TCP/UDP TCP&#xff08;Transmission Control Protocol&a…

【深度学习|目标跟踪】DeepSort 详解

DeepSort详解 1、Sort回顾2、DeepSort的状态向量3、DeepSort的外观特征4、DeepSort的track状态5、DeepSort的代价矩阵以及门控矩阵6、DeepSort的级联匹配 1、Sort回顾 查看这篇博客 2、DeepSort的状态向量 Sort中的卡尔曼滤波使用的目标的状态向量是一个7维的向量&#xff0c…

无人机在森林中的应用!

一、森林资源调查 无人机可以利用遥感技术快速获取所需区域高精度的空间遥感信息&#xff0c;对森林图斑进行精确区划。相较于传统手段&#xff0c;无人机调查具有低成本、高效率、高时效的特点&#xff0c;尤其在地理环境条件不好的区域&#xff0c;调查人员无法或难以到达的…