C++STL之list容器

news2024/12/24 21:24:35

一:list特性

  • list为带哨兵位双向循环链表,支持任意位置的插入和删除。

  • 与(array,vector,deque)相比,list的移除元素效率更高。

  • 最大缺陷是不支持[]重载,不支持随机访问,只能通过迭代器进行线性开销的迭代。

二:list的排序

list无法使用算法库中的sort排序,算法库的sort底层是快排,需要三数取中,需要传入随机访问迭代器,所以list不适用。但是list的类域中自身提供了一种sort排序,底层是归并排序

通过图片分析,list的排序比vector调用算法库中的排序效率低,甚至比先将list数据拷贝给vector,再调用算法库的排序的效率还要低。

三:迭代器

1:迭代器失效

  • erase迭代器失效

  • insert迭代器不失效

2:迭代器种类

  • 单向迭代器,只能++,如单链表和哈希表。

  • 双向迭代器,支持++和--,如双向循环链表

  • 随机访问迭代器,支持++--和+-,如vector和string。

4:迭代器的价值

  • 使用封装,不能暴露底层的实现细节

  • 提供统一的访问方式,降低使用成本,这也是STL设计巧妙之处。

5:模拟实现

5.1:原生指针迭代器和封装迭代器类

  • vector和string在物理空间上是连续的,我们之前模拟实现的时候,采用typedef将原生指针定义为迭代器,vector和string是双向迭代器,迭代器的++和--都是跨过一个对象的大小,也就是T的大小。因为在物理空间连续,所以可以直接用原生指针。

  • 但是list在物理空间上不连续,如果用原生指针,因为不清楚前后节点在物理空间上谁是前谁是后,所以用原生的++--就无法访问到下一个节点,因此我们可以使用封装+运算符重载实现迭代器。

对于每一个节点,在C语言的时候是用struct,在这里因为不知道节点是该给公共权限还是私有,所以也直接设计成struct。

迭代器代码

迭代器模板中的Ref和Ptr后续讲解。迭代器类中设计好相关运算符的重载即可。

5.2:list类初步代码

5.3:const迭代器

const迭代器错误写法

如果给it迭代器添加const权限,那么it就无法更改,也就是it无法++--,这样显然不行。

因此我们可以考虑给迭代器类模板添加第二个参数。在list类模板中将普通迭代器和const迭代器使用同一个类模板创建2种类型,也就是第二个参数分别传普通的T和const T。因为const迭代器无法修改迭代器所指向的内容,因此传引用没有拷贝开销,所以第二个参数分别传T&和const T&。

因为多了一个参数,比如设计*重载的时候,返回值需要设置为__list_iterator<T, Ref>&,这样名字过长,因此我们可以这样。(Ptr下面再讲)

这里非const和const迭代器采用添加Ref参数的好处是,如果不这样写,就需要在迭代器类模板中分别实现每个函数的const和非const版本,这样一来代码重复量太大,不美观。

5.4:->重载

list类模板中,T是对象的类型,如果T是struct类型,想要通过迭代器解引用访问T对象的数据,就必须在迭代器类中提供->重载。

这里使用Ptr,是考虑有const和非const的迭代器,在list中我们就可以这样传参。

因为如果访问struct的成员,需要使用->,而struct指针可以做到,因此第三个参数要设计成指针形式,对于非const传T*,对于const传const T*,因此在迭代器的类模板中就可以添加第三个参数Ptr,表示指针,那么->重载的返回值就可以为Ptr。

我们一般可能遇到这种情景,为什么->这样重载就可以访问到数据呢?

it->我们知道应该是it.operator->(),这样的返回值是Pos*,Pos*_row这如何访问数据?

实际上,这里it->_row的本来面貌是it->->_row,这样就容易懂了,Pos*->_row就是结构体指针访问到数据,而编译器为了可读性,在这里省略了一个->,因此这里比较难懂。

5.5:模拟总代码

5.6:拷贝构造现代写法

和前面一样,直接 使用算法库的swap是一个深拷贝,代价太大,所以我们可以换个思路使用算法库的swap交换头节点即可,因为list只要头结点知道就可以访问下面的数据。

拷贝构造比如lt1(lt2),目的是将lt2的内容给lt1,不能改变lt2的内容,因此需要传const&

拷贝构造不能直接传值传参,必须用传引用传参,否则无限递归。

而如果通过临时对象构造一个lt2,可以再设计一个前后迭代器的构造函数,一开始设计的时候是没有empty这个函数的,因为如果将list初始化的代码直接放在构造函数中,这里我们设计拷贝构造的时候,lt1对象还没有实例化,仍然是一个类,所以不会去调用构造函数,所以头节点就是一个随机值。所以如果将随机值交换给temp,temp出了当前函数作用域后自动调用析构,析构的就是随机值,因此我们需要将初始化的代码单独使用一个empty函数。

5.7:=重载现代写法

和之前一样,用传值传参,不改变形参的特性。

四:list和vector的区别

  • 底层结构:vector是动态顺序表,连续空间,list是带头双向循环链表,物理空间不连续。

  • 随机访问:vector支持[]重载随机访问,效率O(1),list不支持随机访问,访问效率O(N)

  • 插入和删除:vector任意位置插入和删除的效率比较低(尤其是前中部分元素),需要挪动数据,时间复杂度为O(N),插入的时候需要增容,增容是异地扩容,拷贝元素,释放旧空间,效率更低。list任意位置插入和删除元素效率高,效率为O(1),不需要挪动数据。

  • 空间利用率:vector底层为连续空间,不易造成内存碎片,空间利用率高,高速缓存命中率高,list底层节点动态开辟,小节点容易造成内存碎片,空间利用率低,高速缓存命中率低

  • 迭代器:vector是原生态指针,list采用封装+函数重载。

  • 迭代器失效:vector的insert可能导致扩容,迭代器失效,erase也会导致当前pos位置的迭代器失效。list的insert迭代器不会失效,erase导致当前迭代器失效。

  • 使用场景:vector适用于高效存储,随机访问,不关心插入删除效率。list适用于大量插入和删除操作,不关心随机访问。

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

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

相关文章

基于 EventBridge API Destination 构建 SaaS 集成实践方案

作者&#xff1a;赵海 引言 事件总线 EventBridge 是阿里云提供的一款无服务器事件总线服务&#xff0c;支持阿里云服务、自定义应用、SaaS 应用以标准化、中心化的方式接入&#xff0c;并能够以标准化的 CloudEvents 1.0 协议在这些应用之间路由事件&#xff0c;帮助您轻松构…

Mockjs入门基础概念与使用

文章目录Mockjs入门使用1、概述2、安装引入3、语法规范3.1 数据模板定义规范&#xff08;DTD)3.1.1 DTD介绍3.1.2 规范实例演示字符串String数字Number布尔Boolean对象Object数组Array函数Function正则表达式RegExp3.2 数据占位符定义规范DPD4、关于Mock.mock()方法4.1 参数介绍…

RabbitMQ 常见面试题

RabbitMQ 常见面试题 1.为什么要用消息队列? (消息队列的应用场景?) 2.各种消息队列产品的比较? 3.消息队列的优点和缺点? 4.如何保证消息队列的高可用? 5.如何保证消息不丢失? 6.如何保证消息不被重复消费?(如何保证消息消费的幂等性&#xff09; 7.如何保证消息消费的…

PMP证书好考吗?

PMP 还是很好考的&#xff0c;各大机构 3A 的人也很多&#xff0c;我的备考经验分享给大家参考下&#xff0c;大家可以取长补短&#xff0c;找到适合自己的备考方法&#xff1a;一、复习计划的制定根据之前在培训班共同奋斗的小伙伴学习时间统计&#xff0c;平均每天的学习时间…

我的第一门编程语言

元旦节在家重温了一遍《三体》&#xff0c;看到下面一段描写&#xff1a;监听部的计算机系统也远比发射部庞大复杂&#xff0c;叶文洁第一次走进主机房时&#xff0c;看到一排阴极射线管显示屏&#xff0c;她惊奇地发现&#xff0c;屏幕上竟滚动着一排排程序代码&#xff0c;可…

KITTI评价指标学习

在pointpillars完成训练后,可以看到对于目标检测的评估,据了解,这是kitti的标准目标检测格式,所以了解了一下. 在generate label finished后,可以看到类别Car对应的AP(Average precision)有3个0.70,分别对应的是Kitti object detection中,被分为Easy, Moderate,和Hard三种级别物…

算法训练 —— 哈希

目录 1. LeetCode242. 有效字母的异位词 2. LeetCode349. 两个数组的交集 3. LeetCode350. 两个数组的交集II 4. LeetCode202. 快乐数 5. LeetCode1. 两数之和 1. LeetCode242. 有效字母的异位词 有效字母的异位词 本题的含义就是判断两个字符串是否相同&#xff1b; 我们…

文档管理降低运营成本的 5 大方法

文档管理降低运营成本的 5 大方法 正在寻找降低成本和最大化生产力的方法的首席财务官和首席信息官已经知道&#xff0c;良好的文档管理可以在几个月内收回成本。数字文档管理&#xff08;有时称为“企业内容管理”或 ECM&#xff09;通过自动化工作流程和消除耗时的手动任务来…

第三十四讲:神州路由器远程管理

1、路由器的带外管理 Username: admin Password: Router>ena Router#conf Router_config#username dcn password 123456 Router_config#enable password 0 789 Router_config#aaa authentication enable default enable Router_config# aaa authentication login de…

Spring学习笔记1

1.核心概念 IoC&#xff08;Inversion of Control&#xff09;控制反转 对象的创建控制权由程序转移到外部&#xff0c;这种思想称为控制反转 Spring技术对IoC思想进行了实现 Spring提供了一个容器&#xff0c;称为IoC容器&#xff0c;用来充当IoC思想中的“外部” IoC容器负责…

测试小白必备!初级软件测试面试题题库,你绝对要用

软件测试的面试过程中&#xff0c;面试官往往都会根据你面试的职位&#xff0c;提问一些相关的软件测试知识&#xff0c;而很多人为了能够提高的自己在面试当中的通过率&#xff0c;都会在面试前做好充足的准备。比如刷面试题&#xff0c;背答案、准备面试话术这些。今天&#…

JSP ssh 桌面网站系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 JSP ssh 桌面网站系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模 式开发。开发环境为TOMCAT7.0,My…

mes制造执行系统软件适用于哪些行业,有你所处的行业吗?

MES作为一种面向企业工厂生产加工的软件&#xff0c;为企业制造做出了巨大的贡献。虽然MES很实用很简单&#xff0c;但是也凸显了一个问题&#xff0c;有一些企业的生产方式是不适用于MES系统的。那具体哪些行业适合使用MES&#xff0c;哪些不适合。本文将为大家做详细的介绍。…

【Threejs】关于物体在场景中的阴影问题

一、基础知识 1、摄像机的属性结构 先了解一下摄像机THREE.Camera的四个基本参数 2、渲染器设置 render需要开启阴影渲染&#xff0c;这一点是大前提&#xff1a; renderer new THREE.WebGLRenderer();renderer.setSize(width, height);renderer.setClearColor(0x274F80,…

π122E31Q 超低功耗 200Mbps高速率 双通道数字隔离器兼容代替ADuM1201WURZ

π122E31Q 超低功耗 200Mbps高速率 双通道数字隔离器兼容代替ADuM1201WURZ&#xff0c;具有出色的性能特征和可靠性&#xff0c;整体性能优于光耦和基于其他原理的数字隔离器产品。 产品传输通道间彼此独立&#xff0c;可实现多种传输方向的配置&#xff0c;可实现 3.0kVrms 隔…

Python全栈开发(三)——python基础语法(二)

我们昨天说了python的数据类型&#xff0c;今天说说python的缩进规则和函数、python的顺序语句结构&#xff0c;条件和分支语句以及循环语句。缩进不规范会报错&#xff08;IndentationError: unexpected indent&#xff09;&#xff0c;python的函数使用&#xff0c;从定义到实…

【区块链 | EVM】深入理解学习EVM - 深入Solidity数据存储位置:存储

研究Solidity存储引用和智能合约存储布局 原文链接: https://betterprogramming.pub/all-about-solidity-data-locations-part-i-storage-e50604bfc1ad这是深入Solidity数据存储位置系列的另一篇。在今天的文章中,我们将更详细地介绍EVM中的一个重要数据位置:存储(Storage)…

feign简介与实战

一、JAVA 项目中实现远程接口调用 1&#xff09;Httpclient HttpClient 是 Apache Jakarta Common 下的子项目&#xff0c;用来提供高效的、最新的、功能丰富的支持 Http 协议的客户端编程工具包&#xff0c;并且它支持 HTTP 协议最新版本和建议。HttpClient 相比传统 JDK 自带…

APS生产排产软件在金属加工行业的应用

金属加工简称金工&#xff0c;指人类对由金属元素或以金属元素为主构成的具有金属特性的材料进行加工的生产活动。是一种把金属物料加工成为物品、零件、组件的工艺技术&#xff0c;包括了桥梁、轮船等的大型零件&#xff0c;乃至引擎、珠宝、腕表的细微组件。它被广泛应用在科…

C++入门(一)

目录 一. 关键字 二. 命名空间 三. 输入&输出 1.输出 2.输入 四. 缺省参数 1.全缺省参数 2.半缺省参数 五. 函数重载 1.类型 2.原理 一. 关键字 简单了解一下都有哪些关键字 二. 命名空间 在c语言的学习之中&#xff0c;我们知道&#xff0c;在同一…