list的一些特性(C++)

C++ STL 库中的 std::list 是一个带头双向循环链表,使用之前需要包 <list.h>头文件,它和vector的使用高度类似。

构造

list支持多种构造方式

默认构造函数:创建一个空的列表。

拷贝构造函数:从另一个相同类型的列表创建一个新的列表。

范围构造函数:从一对迭代器指定的范围内复制元素到新的列表中。

初始值列表构造函数:使用初始化列表(initializer list)创建一个包含指定元素的列表。

填充构造函数:创建一个包含指定数量相同元素的列表。

cpp 复制代码
#include<iostream>
#include<list>
using namespace std;
int main()
{
	list<int> a; //默认构造函数
	list<int>b(a);//拷贝构造函数
	list<int> b(5,1);//填充构造函数
	list<int> c(b.begin(),b.end());//范围构造函数
	list<int> d = { 1,2,3,4,5,6 };//初始值列表构造函数

	int arr[5] = { 1,2,3,4,5 };
	list<int> e = { arr,arr + 5 };//左闭右开

	return 0;
}

也可以传数组的指针

指针就是一种特殊迭代器,前提是这个指针指向数组

迭代器的行为本质模拟的就是指向数组的指针

例如 sort算法,传迭代器区间就可以排序,数组的指针也行

list迭代器类型

迭代器是通用的相似的遍历容器的方式,并且封装了容器底层,屏蔽了容器结构的差异,和底层的实现细节

简单来说就是,上层都是iterator,底层的实现细节都封装起来了

因为c++是面向对象的语言,与面向过程不一样,它关注的是有那几个类和对象,是几个类实现,以及它们之间的关联关系,不关注其底层结构

从功能角度,迭代器分为三种类型

单向,双向,随机

它们的共同点和不同点:

都支持++,*,!=

单向迭代器只支持++

双向迭代器支持 ++,--

随机迭代器支持 ++,--,+,-

都typedef为iterator

list就是双向迭代器

随机迭代器可以一下子跳到某个位置,加到某个位置,双向迭代器就不行

一个算法,不是所有的容器都可以使用,算法对迭代器是有一些要求

算法迭代器的名字就是要求

比如链表list是双向迭代器,就不能给到sort,sor算法要求的是随机迭代器

由于 std::list 使用的是双向迭代器(bidirectional iterators),它不支持随机访问操作,因此不能直接使用 std::sort。

它们可以认为是继承关系,比如随机是特殊的双向,是特殊的单向 (父类是特殊的子类),所以子类能进去的,父类就能进去

sort

list不能用算法库的sort,所以它自己实现了一个sort

但是list自己实现的sort的性能没有算法库的sort的性能好

算法库的,底层是快排

list使用的是归并排序

虽然两个算法时间复杂度一致

但是在release版本下测性能时,数据量一大,两者所用时间的的差距就会很明显,算法库的sort所用时间会明显更少

即便是将list转成vector类型再使用算法库的sort也比直接使用list自带的sort的效率要高不少

所以在数据量大的情况下,最好不要直接排,而是拷到vector再排

原因:

一个是连续的内存,一个是小块小快的内存,排序需要修改内存上的数据,cpu的速度太快,内存跟不上,就需要使用到缓存

内存会看数据在不在缓存,在就叫命中,不在就叫不命中

如果不在,内存就会将数据先加载到缓存,再让cpu进行访问

内存一般一次会读很多内存,不会只加载指定的几个字节,而是会加载一段数据,相比较链表,连续存放的数组的命中率就会比较高

remove

erase和remove的区别

remove函数不改变容器的空间大小,是因为它的设计目的是为了提高效率。它通过移动元素的方式,将不等于指定值的元素移到容器的前部,而等于指定值的元素移到容器的后部,从而实现了逻辑上的"删除"。但是,这些元素仍然存在于容器中,只是不再被迭代器所指向。因此,容器的物理大小并没有改变。

为了真正删除这些元素,需要配合erase函数使用,erase函数会根据remove返回的迭代器来删除容器尾部的元素,从而改变容器的大小。

删除值,erase是删除迭代器结点

相关推荐
消失的旧时光-19432 小时前
从 Kotlin 到 Dart:为什么 sealed 是处理「多种返回结果」的最佳方式?
android·开发语言·flutter·架构·kotlin·sealed
yq1982043011562 小时前
静思书屋:基于Java Web技术栈构建高性能图书信息平台实践
java·开发语言·前端
一个public的class2 小时前
你在浏览器输入一个网址,到底发生了什么?
java·开发语言·javascript
Jinkxs2 小时前
Gradle - 与Groovy/Kotlin DSL对比 构建脚本语言选择指南
android·开发语言·kotlin
&有梦想的咸鱼&2 小时前
Kotlin委托机制的底层实现深度解析(74)
android·开发语言·kotlin
我在人间贩卖青春2 小时前
C++之继承的方式
c++·private·public·protected·继承方式
BD_Marathon2 小时前
设计模式——依赖倒转原则
java·开发语言·设计模式
devmoon3 小时前
在 Polkadot Runtime 中添加多个 Pallet 实例实战指南
java·开发语言·数据库·web3·区块链·波卡
Evand J3 小时前
TDOA(到达时间差)的GDOP和CRLB计算的MATLAB例程,论文复现,附参考文献。GDOP:几何精度因子&CRLB:克拉美罗下界
开发语言·matlab·tdoa·crlb·gdop
野犬寒鸦3 小时前
从零起步学习并发编程 || 第七章:ThreadLocal深层解析及常见问题解决方案
java·服务器·开发语言·jvm·后端·学习