C++ -- list

一.lisit的介绍

1.list是属于STL的一部分,list可以在链表中的任意位置进行插入和删除操作的序列式容器,并且这个容器可以前后双向迭代,这是由于双向循环链表的特殊性。

2.list的底层是带头双向循环链表结构,双向链表中的每个元素都存在不同的节点之中,所以它的迭代器并不能通过普通的指针进行实现,而是需要通过它的next指向和prev指向来模拟迭代器。

3.list优势是可以在任意地方进行O(1)的时间复杂度进行插入,移除,这是因为它每个节点独立出来的特点。但是也正因如此,它的查改排序效率是低下的,它并不能像vector一样用下标访问数据,每次都需要遍历链表。

4.与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素。

二.list的使用

以下展示一些list的重要接口,我们学习能够熟练使用这些接口就能够掌握链表l

|---------------------------------------------------------------|--------------------------------------------------|
| 构造函数 | 接口说明 |
| list (size_type n, const value_type& val = value_type()) | 构造的list中包含n个值为val的元素 |
| list() | 构造空的****list |
| list (const list& x) | 拷贝构造函数 |
| list (InputIterator first, InputIterator last) | **[first, last)区间中的元素构造list** |

list迭代器的使用

|-------------|-----------------------------------------------------------------------------------------------------------------|
| 函数声明 | 接口说明 |
| begin end | 返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器 |
| rbegin rend | 返回第一个元素的reverse_iterator,end位置返回最后一个元素下一个位置的reverse_iterator,begin位置 |

1. begin与end为正向迭代器,对迭代器执行++操作,迭代器向后移动
2. rbegin(end)与rend(begin)为反向迭代器,对迭代器执行++操作,迭代器向前移动

list容量函数

|-----------|------------------------------------------------------|
| 函数声明 | 接口说明 |
| empty | 检测list是否为空,是返回true,否则返回****false |
| size | 返回list中有效节点的个数 |

list操作函数

|----------------|------------------------------------------|
| 函数声明 | 接口说明 |
| push_front | list首元素前插入值为val的元素 |
| pop_front | 删除list中第一个元素 |
| push_back | list尾部插入值为val的元素 |
| pop_back | 删除list中最后一个元素 |
| insert | list position位置中插入值为****val |
| erase | 删除list position位置的元素 |
| swap | 交换两个list中的元素 |
| clear | 清空list中的有效元素 |

三.list的模拟实现

1.首先定义节点类

2.定义迭代器类

这里使用了三个模板参数是为了在list外部构建迭代器的时候能够通过传const或者非const类型的参数构建const或者非const迭代器。

迭代器具体实现

可以看到这里对迭代器的一些常见操作进行了重载,因为list节点独立的特殊性,我们需要对这些操作进行特殊处理。

3.list类具体实现

list类中只有一个头节点和size大小。构造这里没有实现其他复杂的,头节点用ListNode的默认构创建。

迭代器接口

插入删除操作

这里需要注意的是插入删除以后要返回一个迭代器,因为原来的迭代器插入操作过后在逻辑上已经是失效的了,删除时这个节点直接没有了。

四.list与vector的对比

list和vector的底层结构不同,导致特性以及应用场景大不相同

|-------------------------------|----------------------------------------------------------------------------------------|-------------------------------------------------------|
| | vector | list |
| | 动态顺序表,一段连续空间 | 带头结点的双向循环链表 |
| 访 | 支持随机访问,访问某个元素效率O(1) | 不支持随机访问,访问某个元素 效率****O(N) |
| | 任意位置插入和删除效率低,需要搬移元素,时间复杂O(N),插入时有可能需要增容,容:开辟新空间,拷贝元素,释放旧空间,导致效率更低 | 任意位置插入和删除效率高,不需要搬移元素,时间复杂度为O(1) |
| | 底层为连续空间,不容易造成内存碎片,空间利用率****高,缓存利用率高 | 底层节点动态开辟,小节点容易造成内存碎片,空间利用率低,缓存利用率低 |
| | 原生态指针 | 对原生态指针
(节点指针)进行封装 |
| | **在插入元素时,要给所有的迭代器重新赋值,因为插入
元素有可能会导致重新扩容,致使原来迭代器失效,删
**除时,当前迭代器需要重新赋值否则会失效
| 插入元素不会导致迭代器失效,删除元素时,只会导致当前迭代器失效,其他迭代器不受影响 |
| 使 | 需要高效存储,支持随机访问,不关心插入删除效率 | 大量插入和删除操作,不关心随****机访问 |

相关推荐
优雅的潮叭13 小时前
c++ 学习笔记之 chrono库
c++·笔记·学习
星火开发设计13 小时前
C++ 数组:一维数组的定义、遍历与常见操作
java·开发语言·数据结构·c++·学习·数组·知识
月挽清风14 小时前
代码随想录第七天:
数据结构·c++·算法
TTGGGFF14 小时前
控制系统建模仿真(一):掌握控制系统设计的 MAD 流程与 MATLAB 基础运算
开发语言·matlab
2501_9444241214 小时前
Flutter for OpenHarmony游戏集合App实战之贪吃蛇食物生成
android·开发语言·flutter·游戏·harmonyos
Lhuu(重开版15 小时前
JS:正则表达式和作用域
开发语言·javascript·正则表达式
点云SLAM15 小时前
C++内存泄漏检测之Windows 专用工具(CRT Debug、Dr.Memory)和Linux 专业工具(ASan 、heaptrack)
linux·c++·windows·asan·dr.memory·c++内存泄漏检测·c++内存管理
仙俊红15 小时前
Java Map 家族核心解析
java·开发语言
浅念-15 小时前
C语言小知识——指针(3)
c语言·开发语言·c++·经验分享·笔记·学习·算法
code_li16 小时前
聊聊支付宝架构
java·开发语言·架构