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

相关推荐
我在人间贩卖青春2 分钟前
C++之new和delete
c++·delete·new
Z9fish8 分钟前
sse哈工大C语言编程练习20
c语言·开发语言·算法
Trouvaille ~11 分钟前
TCP Socket编程实战(三):线程池优化与TCP编程最佳实践
linux·运维·服务器·网络·c++·网络协议·tcp/ip
June`20 分钟前
高并发网络框架:Reactor模式深度解析
linux·服务器·c++
小镇敲码人31 分钟前
剖析CANN框架中Samples仓库:从示例到实战的AI开发指南
c++·人工智能·python·华为·acl·cann
萧鼎32 分钟前
Python 包管理的“超音速”革命:全面上手 uv 工具链
开发语言·python·uv
Anastasiozzzz1 小时前
Java Lambda 揭秘:从匿名内部类到底层原理的深度解析
java·开发语言
刘琦沛在进步1 小时前
【C / C++】引用和函数重载的介绍
c语言·开发语言·c++
机器视觉的发动机1 小时前
AI算力中心的能耗挑战与未来破局之路
开发语言·人工智能·自动化·视觉检测·机器视觉
HyperAI超神经1 小时前
在线教程|DeepSeek-OCR 2公式/表格解析同步改善,以低视觉token成本实现近4%的性能跃迁
开发语言·人工智能·深度学习·神经网络·机器学习·ocr·创业创新