【C++进阶】STL容器--list使用迭代器问题分析

news2024/11/16 21:37:29

目录

前言

1. list的基本使用

1.1 list构造函数

1.2 list迭代器

 1.3 list capacity

1.4 list元素访问

 1.5 list 修改操作

insert

erase

 swap

 resize

 clear

2. list失效迭代器问题

3. list使用算法库函数问题

 总结


前言

        list(链表)在C++中非常重要的容器,它本质是一个带头双向循环链表。本文的主要内容是介绍list的基本使用以及对list迭代器问题。

在这里插入图片描述

1. list的基本使用

 学习一种新的容器,首先我们需要先了解它的接口;

 在C++的STL标准库中,list是一个带头双向循环链表;

 list和vector不同,它不支持[ ]下标随机访问;

list是一个双向链表,它的元素在内存中不是连续存储的,因此并不需要像vector一样预留容量或者调整容量

1.1 list构造函数

 C++98中默认有4中构造函数:

 有四种构造方法:

  • 默认无参构造
list<int> lt1;//无参构造
  • n个val构造
list<int> lt2(10,0); // 10个0初始化
  •  迭代器区间构造
vector<int> v{1,2,3,4,5};
list<int> lt3(v.begin(),v.end());
  •  拷贝构造
list<int> lt4(10,0);
list<int> lt5(lt4);

 除此之外还有比较常用的初始值设定项列表构造;

  •  initializer list构造(初始值设定项列表构造)
list<int> lt = {1, 2, 3, 4, 5};

1.2 list迭代器

 list迭代器本质并不是指针,为了方便理解,可暂时将迭代器理解成一个指针,该指针指向list中的某个节点;

 这4个迭代器接口大家都很熟悉,但需要注意的是list中它们的指向;

  •  list迭代器遍历
list<int> lt = { 1, 2, 3, 4, 5 };
list<int>::iterator it = lt.begin();
while (lt.end() != it)
{
	cout << *it << ' ';
	it++;
}
  •  范围for遍历
for (auto e : lt)
{
	cout << e << ' ';
}

范围for循环确实是本质上是迭代器遍历,在执行时会被替换成迭代器;

注意:

         在使用list迭代器时,我们往往使用的是it!=l.end(),而不是it<l.end(),因为list空间并不连续,每个节点的地址都不同(无法确认大小关系),在string和vector中,空间是连续的,可以使用;

 1.3 list capacity

 

 使用操作较为简单,使用list对象即可调用:

lt.empty();
lt.size();

1.4 list元素访问

 

 使用操作较为简单,使用list对象即可调用:

lt.front();
lt.back();

 1.5 list 修改操作

这里我们可以参考cplusplus上边的接口;

 这里我就介绍一些比较常用的,其他的接口使用可以去查阅;

头插、头删、尾插、尾删我就不再详细介绍;注意这些操作只能插入删除一个元素!

assign接口功能是新元素替换列表中的内容,它的功能我们完全可以使用list的构造函数替代,这里不再详细介绍;

insert

 

  •  使用单个值插入
list<int> mylist = {1, 2, 3, 4, 5};
auto it = mylist.begin();
it++; // 将迭代器it移动到第二个位置
mylist.insert(it, 10); // 在it位置插入值为10的元素
  • 使用相同值填充插入
list<int> mylist = {1, 2, 3, 4, 5};
auto it = mylist.begin();
it++; // 将迭代器it移动到第二个位置
mylist.insert(it, 3, 10); // 在it位置插入3个值为10的元素
  • 迭代器区间插入
list<int> mylist = {1, 2, 3, 4, 5};
auto it = mylist.begin();
it++; // 将迭代器it移动到第二个位置
vector<int> vec = {7, 8, 9};
mylist.insert(it, vec.begin(), vec.end()); // 在it位置插入vector中的元素
erase

 

  •  删除单个元素
list<int> mylist = {1, 2, 3, 4, 5};
auto it = mylist.begin();
it++; // 将迭代器it移动到第二个位置
mylist.erase(it); // 删除it位置的元素
  • 删除范围内的元素:
list<int> mylist = {1, 2, 3, 4, 5};
auto it1 = mylist.begin();
auto it2 = mylist.begin();
advance(it1, 1); // 将迭代器it1移动到第二个位置
advance(it2, 3); // 将迭代器it2移动到第四个位置
mylist.erase(it1, it2); // 删除从it1到it2范围内的元素

 注意list迭代器不支持使用+或-的操作来进行移动;所以这里使用advance函数来移动迭代器;

 swap

swap函数交换两个list的内容:

list<int> list1 = {1, 2, 3};
list<int> list2 = {4, 5, 6};
list1.swap(list2); // 交换list1和list2的内容
 resize

 resize函数调整list的大小:

list<int> mylist = {1, 2, 3, 4, 5};
mylist.resize(3); // 将mylist的大小调整为3,删除多余的元素
mylist.resize(5, 100); // 将mylist的大小调整为5,多出的元素用100填充

 list没有reserve接口

 clear

clear函数清空list的内容:

list<int> mylist = {1, 2, 3, 4, 5};
mylist.clear(); // 清空mylist的内容,mylist现在为空

2. list失效迭代器问题

         前面说过,此处大家可将迭代器暂时理解成类似于指针,迭代器失效即迭代器所指向的节点的无效,list的底层结构为带头结点的双向循环链表,在list中进行插入时是不会导致list的迭代
器失效;

list迭代器失效只会在erase删除操作时发生

删除节点后,节点的数据就会被释放,再使用迭代器访问这个节点,此时节点已经失效;

前边我们也提到过,可以通过返回值的方法来避免迭代器的非法访问;

 节点被删除后,自动返回下一个位置的迭代器;

3. list使用算法库函数问题

 如果要对链表进行排序呢?

其实list自己封装的有sort接口,list链表的sort函数使用的是归并排序算法;那它为什么不用算法库里的sort;

原因很简单,其实就是迭代器不兼容;

 算法库里的sort它的参数是RandomAccessIterator,也就是随机访问迭代器;

这里就要补充一点知识,从不同容器的迭代器出发,容器不同迭代器实现也不同,那么迭代器的特性也不同;

根据迭代器的特性大致可以先分为三类: 

  • 单向迭代器(Forward Iterator) 
  • 双向迭代器(Bidirectional Iterator)
  • 随机访问迭代器(Random Access Iterator)

 单向迭代器: 迭代器仅++操作,单链表

 双向迭代器:迭代器支持++、--操作,双向链表

 随机访问迭代器:迭代器支持++/--/+/-操作,vector、string

 怎么分辨是否可以使用算法接口?

单向迭代支持++操作,满足所有迭代器的操作,三种类型的迭代器类型接口函数都可以使用;

 双向迭代器支持++/--操作,满足随机访问迭代器的操作,那它就可以使用参数类型为双向迭代器类型的接口函数,参数类型为随机访问迭代器类型的接口;

它就有向上兼容的特性;

 总结:

  • 单向迭代器可以使用三种迭代器类型的接口;
  • 双向迭代器可以使用:双向迭代器、随机迭代器类型的接口;
  • 随机迭代器仅可以使用随机迭代器类型的接口;

 虽然list自己实现的有sort接口,但还是不建议使用,它的效率非常的低;

它甚至还没有这样操作的速度快:

将list数据拷贝到vector中排序,然后将排序好的数据拷贝回list;


 总结

         本文主要介绍的是list的一些基本使用,以及list迭代器问题和list使用算法库函数的问题。list的接口函数不多,但是在使用算法库函数时需要注意迭代器的类型;以上便是本期的全部内容,希望对你有所帮助,感谢阅读!

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

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

相关文章

怎么把音频转换成二维码?把音频制作成二维码的方法

现在很多二维码被用来作为信息传递的一种方式&#xff0c;常见的类型包括文本、图片、音视频等等。选择这种方式的好处在于&#xff0c;不仅制作起来非常简单&#xff0c;有效的降低成本&#xff0c;而且便捷性也比较强。那么如何将音频格式的文件做成二维码图片呢&#xff1f;…

一文读懂:怎样将 MongoDB 转变为预测数据库?操作详解来了!

商界对人工智能 (AI) 和机器学习 (ML) 的兴趣日益浓厚。ML/AI 的预测功能能够以比人工分析更快的速度从检测到的模式中快速获得见解。此外&#xff0c;生成式机器学习应用程序&#xff08;如 OpenAI 和 Hugging Face&#xff09;的最新进展为企业提供了强大工具以用于生成和分析…

arcgis 面要素shp数据处理

面要素是工作中用到最多的&#xff0c;那么面要素是如何形成的呢&#xff0c;主要还是由闭合的线要素转换而成。在面要素数据中常用的有以下几点&#xff1a; 一、 线转面&#xff08;要素转面&#xff09; 通过上一篇得到了点转线的要素&#xff0c;那么根据上节的线要素&am…

【Linux C | 进程】Linux 进程间通信的10种方式(2)

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

jieba.net使用NuGet管理器安装后初始化TfidfExtractor对象时报错

在引用安装jieba.net后,引用的Resources下只有如图几个文件 导致初始化TfidfExtractor时报错,报找不到 Could not find file E:\\TZKJNet\\robotindustry\\modules\\Tzkj.Superhard.SupplyDemand\\src\\Tzkj.Superhard.SupplyDemand.HttpApi.Host\\bin\\Debug\\net7.0\\Reso…

【C++干货基地】C++入门篇:输入输出流 | 缺省函数 | 函数重载(文末送书)

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 引入 哈喽各位铁汁们好啊&#xff0c;我是博主鸽芷咕《C干货基地》是由我的襄阳家乡零食基地有感而发&#xff0c;不知道各位的…

[leetcode] 18. 四数之和

文章目录 题目描述解题方法排序 双指针java代码 相似题目 题目描述 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;若两个四元组元素一一对应&a…

《解锁R统计分析:深度探索R Commander图形界面》

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 在数据科学与大数据技术的浪潮中&#xff0c;R…

Python爬取猫眼电影专业评分数据中的应用案例

在数据分析和可视化展示中&#xff0c;获取准确的电影专业评分数据至关重要。猫眼电影作为中国领先的电影信息与票务平台&#xff0c;其专业评分对于电影行业和影迷的数据来说具有重要意义。通过Python爬虫技术&#xff0c;我们可以实现从猫眼电影网站上自动获取这些数据目标。…

go swagger怎么玩(使用swagger为go项目生成python的SDK)

异常详细&#xff01;所到之处&#xff0c;问题全量解决、你值得拥有&#xff01; 目录 go方面需要做的准备&#xff08;步骤代码&#xff09; 生成对应语言的SDK 生成后怎么调用验证 提示&#xff1a;生成哪种语言的SDK只是本文的其中一步&#xff0c;具体哪种语言可以选择…

数字图像处理(实践篇)二十七 Python-OpenCV 滑动条的使用

目录 1 涉及的函数 2 实践 1 涉及的函数 ⒈ setWindowProperty()用于设置GUI应用程序的属性 cv2.setWindowProperty(windowsName, prop_id, prop_value) 参数: ①

Oracle篇—分区表的管理(第二篇,总共五篇)

☘️博主介绍☘️&#xff1a; ✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ ✌✌️擅长Oracle、MySQL、SQLserver、Linux&#xff0c;也在积极的扩展IT方向的其他知识面✌✌️ ❣️❣️❣️大佬们都喜欢静静的看文章&#xff0c;并且也会默默的点赞收藏加关注❣…

Wordpress seo优化该怎么做?

Wordpress作为开源管理系统&#xff0c;目前已然是世界上最流行的cms之一&#xff0c;这不仅仅因为他开源&#xff0c;对用户友好&#xff0c;让任何人都能轻而易举的制作网站&#xff0c;更是因为这套程序对于搜索引擎非常友好&#xff0c;是做谷歌seo的不二之选 Wordpress作为…

消息队列RabbitMQ.03.死信交换机的讲解与使用

目录 一、死信队列(延迟队列) 概念讲解 二、确认消息&#xff08;局部方法处理消息&#xff09; 三、代码实战 1.编写生产者代码&#xff0c;配置消息、直连交换机、路由键 1.1代码解析&#xff1a; 2.配置消费者接受类接受直连交换机的路由键 2.1. String msg&#xff…

nsenter比docker exec更底层的命令

文章目录 nsenter介绍安装方法简单使用 nsenter介绍 nsenter命令是一个可以在指定进程的命令空间下运行指定程序的命令。它位于util-linux包中。典型的用途就是进入容器的网络命令空间。相当多的容器为了轻量级&#xff0c;是不包含较为基础的命令的&#xff0c;比如说ip addr…

响应式Web开发项目教程(HTML5+CSS3+Bootstrap)第2版 例4-7 datalist

代码 <!doctype html> <html> <head> <meta charset"utf-8"> <title>datalist</title> </head><body> <input id"address" list"addressList"> <datalist id"addressList"…

【数据结构】 链队列的基本操作 (C语言版)

目录 一、链队列 1、链栈的定义&#xff1a; 2、链栈的优缺点&#xff1a; 二、链队列的基本操作算法&#xff08;C语言&#xff09; 1、宏定义 2、创建结构体 3、链栈的初始化 4、链队列的入队 5、链队列的出队 6、取链队列的对头元素 7、链队列的销毁 8、链…

4.列表选择弹窗(CenterListPopup)

愿你出走半生,归来仍是少年&#xff01; 环境&#xff1a;.NET 7、MAUI 在屏幕中间弹窗的列表选择弹窗。 1.布局 <?xml version"1.0" encoding"utf-8" ?> <toolkit:Popup xmlns"http://schemas.microsoft.com/dotnet/2021/maui"x…

【AIGC】Diffusers:扩散模型的开发手册说明2

前言 扩散器被设计成一个用户友好且灵活的工具箱&#xff0c;用于构建适合您用例的扩散系统。工具箱的核心是模型和调度程序。然而 DiffusionPipeline 为方便起见将这些组件捆绑在一起&#xff0c;但您也可以解包管道并分别使用模型和调度程序来创建新的扩散系统。 解构 Stab…

uniapp组件库Modal 模态框 的使用方法

目录 #平台差异说明 #基本使用 #传入富文本内容 #异步关闭 #点击遮罩关闭 #控制模态框宽度 #自定义样式 #缩放效果 #API #Props #Event #Method #Slots 弹出模态框&#xff0c;常用于消息提示、消息确认、在当前页面内完成特定的交互操作。 #平台差异说明 AppH5微…