list的模拟实现和学习

发布于:2025-03-27 ⋅ 阅读:(22) ⋅ 点赞:(0)

1. list的介绍及使用

说白了就是带头循环双向循环链表

stl 的两大组件就是容器和算法 ,他们两个之间是通过迭代器进行联系的

这三种算法函数

迭代器的种类 性质(容器底层结构决定)

单项:++             forward_list /哈希(unordered_xxx)

双向:++ / --        list/map/set

随机:++/--/+/-     vector  /string/deque

vector用算法里面的sort 排序效率很高,list不支持库里面的算法sort 但是list里面实现了sort函数,用的是归并排序,效率较低,list.sort唯一的优点就是方便数据量大的时候就不适用了

2. list的深度剖析及模拟实现

merge() 两链表直接归并(先排序)

unique()去重复的数据 ,也是先排序

remove()== find + erase

splic 就是粘接,转移

这里list的迭代器用类封装了,要着重讲一下

带头双向循环,所以节点就用类(struct)封装起来,在list里面new 一个list_node 节点

struct里面构造函数可以  就去构造(new一个自定义类型就是调用拷贝构造)

这里就是用类去封装迭代器 (因为list 节点不连续)迭代器如果直接用Node*来表示,++后就不知道去了什么位置了,所以用类去封装的时候运用运算符重载,就可以经行让类里面_node 指向下一个节点

这样对于++  *   ==  这些运算符就可以按照我们的意思去进行设计

注意:iterator本质就是为了指向要访问的节点,所以类里面还是有Node* 指向节点 本质就是借用类更好的进行对节点指针的操作

对于一些地方加const修饰,比如!=  这是因为传值的时候 传的是lt.end() 这里临时变量具有常性

当然还有const 修饰的迭代器 

如何设计一个const修饰的迭代器呢? 

目的是为了让iterator指向的内容是不能修改的,而iterator本身可以修改指向的节点

如:const T* ptr1   和  T* const ptr2

我们要的是第一种

因为iterator 和const_iterator 的区别就是一个返回值(*重载的返回值)不同,其实我们可以加一个模板参数,来控制这个返回值就可以了,不用再写一个const_iterator了

若为const迭代器 返回的是const T* 所以再加一个模板参数

这就是list 简单的主体部分

3. list与vector的对比

vector与list都是STL中非常重要的序列式容器,由于两个容器的底层结构不同,导致其特性以及应用场景不 同,其主要不同如下:

这个迭代器失效问题同样是用传iterator来处理迭代器失效

完整实现