【C++进阶五】list深度剖析

【C++进阶五】list深度剖析

1.什么是list

STL标准库中的list是一个带头双向循环链表

和vector不同,list没有支持[ ]访问以及resize和reserve容量相关的函数,这是因为list不能随机访问数据,并且list的迭代器的底层不是指针

和vector一样,list也有两个模板参数,但是第二个模板参数是和内存效率相关的,所以现在的学习暂时不用管它(它有缺省值)

2.list的使用

2.1构造函数

cpp 复制代码
list<int> l1;//无参构造
list<int> l2(10,6);//用10个6初始化链表

vector<int> v{1,2,3,4,5,6};
list<int> l3(v.begin(),v.end());//用迭代器区间初始化

list<char> l4('a');//用一个字符来初始化

2.2list迭代器

虽然list的迭代器底层不是指针,但是可以把它理解为指针来使用

迭代器遍历链表:

cpp 复制代码
vector<int> v{1,3,5,7,9,11,13,15};
list<int> l(v.begin(),v.end());

auto it = l.begin();
while(it != l.end())
{
	cout << *it << " ";
	it++;
}

范围for遍历链表:

cpp 复制代码
vector<int> v{1,3,5,7,9,11,13,15};
list<int> l(v.begin(),v.end());
for(auto x : l)
{
	cout << x << " ";
}

注:list不支持随机访问,不能用[]

在写用迭代器遍历容器时,我们往往会写it!=l.end(),而不是it<l.end(),这是因为在list中,空间并不连续,用小于符号很大概率会出错,但是在string和vector中,空间是连续的,用<也没问题

2.3容量操作

和vector一样

常用的四个接口:

2.4增删查改


insert :insert函数要输入一个迭代器位置进行插入,可以插入一个数据或插入一段迭代器区间

erase :erase函数可以删除一个迭代器的数据或者删除一段迭代器区间

clear:list的clear函数是将链表清空(除头节点外)

因为list不像vector一样有size和capacity

cpp 复制代码
vector<int> v{1,5,10,25,40,100,110};
list<int> l(v.begin(),v.end());

auto pos = find(l.begin(),l.end(),40);
l.insert(pos,250);
l.erase(l.begin()+2);
l.clear();

3.list迭代器失效

由于list的底层是双向带头循环链表,所以插入操作时,pos指向的节点的位置始终都是一个位置,它们只改变链接关系,并不连续,所以插入操作并不会导致list迭代器失效

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

删除节点后,当前节点的指针1iterator失效,所以要更新iterator

STL库的erase提供了返回值来解决问题:

4.迭代器类型

迭代器从功能角度可以分类为:

  1. 正向迭代器: forward_iterator,只支持++
  2. 双向迭代器: bidirectional_iterator,支持++--
  3. 随机迭代器: random_iterator,支持++,- -,+和-

常见的容器以及它们的迭代器类型:

算法库的sort函数,它的函数模板支持的是随机迭代器

算法库的reverse函数,它的函数模板支持的是双向迭代器

结论:

  1. 若函数模板给的随机迭代器,则只能传有随机迭代器的容器
  2. 若函数模板给的双向迭代器,则可以传有随机或者双向迭代器的容器
  3. 若函数模板给的单向迭代器则三种迭代器都可以传进来

5.list不能使用的算法库函数

list的迭代器是双向迭代器,而sort函数的函数模板是随机迭代器,所以库函数中的sort无法排序链表

所以list类自己实现了一个不同于算法库的排序:

虽然list有自己的sort函数来排序,但是当数据很多时,list自我实现的sort的效率低的惊人,效率甚至还不如将list的数据导入vector容器,再在vector容器中使用算法库的排序,排完序再导入到list中

相关推荐
枫景Maple3 小时前
C#字典Dictionary的内部实现原理
开发语言·c#
上单带刀不带妹6 小时前
Node.js 中的 fs 模块详解:文件系统操作全掌握
开发语言·javascript·node.js·fs模块
牵牛老人6 小时前
Qt中的QWebSocket 和 QWebSocketServer详解:从协议说明到实际应用解析
开发语言·qt·网络协议
chenglin0166 小时前
制造业ERP系统架构设计方案(基于C#生态)
开发语言·系统架构·c#
凌晨7点6 小时前
控制建模matlab练习13:线性状态反馈控制器-②系统的能控性
开发语言·matlab
要记得喝水6 小时前
汇编中常用寄存器介绍
开发语言·汇编·windows·c#·.net
金智维科技官方6 小时前
常见的大模型分类
人工智能·算法·ai·语言模型·数据挖掘
yzzzzzzzzzzzzzzzzz7 小时前
leetcode热题——有效的括号
算法·
shi57837 小时前
C# 常用的线程同步方式
开发语言·后端·c#
凌晨7点7 小时前
控制建模matlab练习11:伯德图
开发语言·matlab