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) |
| | 底层为连续空间,不容易造成内存碎片,空间利用率****高,缓存利用率高 | 底层节点动态开辟,小节点容易造成内存碎片,空间利用率低,缓存利用率低 |
| | 原生态指针 | 对原生态指针
(节点指针)进行封装 |
| | **在插入元素时,要给所有的迭代器重新赋值,因为插入
元素有可能会导致重新扩容,致使原来迭代器失效,删
**除时,当前迭代器需要重新赋值否则会失效
| 插入元素不会导致迭代器失效,删除元素时,只会导致当前迭代器失效,其他迭代器不受影响 |
| 使 | 需要高效存储,支持随机访问,不关心插入删除效率 | 大量插入和删除操作,不关心随****机访问 |

相关推荐
a伊雪38 分钟前
c++ 引用参数
c++·算法
御形封灵39 分钟前
基于原生table实现单元格合并、增删
开发语言·javascript·ecmascript
应茶茶1 小时前
从 C 到 C++:详解不定参数的两种实现方式(va_args 与参数包)
c语言·开发语言·c++
Data_agent1 小时前
1688获得1688店铺列表API,python请求示例
开发语言·python·算法
2301_764441332 小时前
使用python构建的应急物资代储博弈模型
开发语言·python·算法
丿BAIKAL巛2 小时前
Java前后端传参与接收全解析
java·开发语言
code bean2 小时前
【C++】Scoop 包管理器与 MinGW 工具链详解
开发语言·c++
yanghuashuiyue2 小时前
Java过滤器-拦截器-AOP-Controller
java·开发语言
hetao17338372 小时前
2025-12-11 hetao1733837的刷题笔记
c++·笔记·算法
小冷coding2 小时前
【Java】高并发架构设计:1000 QPS服务器配置与压测实战
java·服务器·开发语言