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

相关推荐
老鱼说AI1 小时前
BPE编码从零开始实现pytorch
开发语言·人工智能·python·机器学习·chatgpt·nlp·gpt-3
星释1 小时前
Rust 练习册 32:二分查找与算法实现艺术
开发语言·算法·rust
William_cl2 小时前
C# ASP.NET Controller 核心:ViewResult 实战指南(return View (model) 全解析)
开发语言·c#·asp.net
wtrees_松阳2 小时前
Flask数据加密实战:医疗系统安全指南
开发语言·python
皮影w2 小时前
Java SpringAOP入门
java·开发语言
Jtti2 小时前
IPv4与IPv6共存下的访问问题排查方法
开发语言·php
周杰伦fans3 小时前
CommunityToolkit.Mvvm(又称MVVM Toolkit) 与 MvvmLight 的核心区别
开发语言·c#·.netcore
小青龙emmm3 小时前
2025级C语言第四次周测题解
c语言·开发语言·算法
树在风中摇曳3 小时前
【牛客排序题详解】归并排序 & 快速排序深度解析(含 C 语言完整实现)
c语言·开发语言·算法