0.概述
list是什么? list本质上就是双向链表
相对与上一篇所讲的vector,我们知道双向链表有它自己的优点,首先空间利用比较灵活,所以省空间.
而且插入删除元素都是常数时间
下面将参照list的源码,将其分为下面几部分去讲
1.结点
既然list是链表,那就必须得定义它自己的结点类
在源码中它的结点是这样子的
2.迭代器
不像vector是连续的内存空间,所以可以直接用指针作为迭代器
在 list中由于是链式存储的,所以得定义一个属于自己的迭代器
直接看一些它的源码
可以看到在迭代器类中 有一个成员变量 node,用来存放该迭代器指向的结点,
可以通过构造函数给node指定指向的结点,
也可以给通过复制构造函数给node指定好另一个迭代器的node指向的结点.
由于list只支持双向迭代器(因为双向链表要支持前移 后移),所以对运算符++ ,-- ,* ,->进行了重载.
注意 在list中插入结点和删除某个结点并不会使其他结点的迭代器失效,
而vector就并非如此,因为插入元素可能导致原有内存重新分配 导致原有迭代器失效
3.数据结构
list是一个双向循环链表,既然是循环,也就是说尾结点的下一个就是头结点,头结点的上一个就是尾结点.
同时只要用一个结点指针指向了其中一个结点,就可以遍历到其他任意结点
在list中定义了一个空白的尾结点指针 用node表示 如下图表示
通过这个node,就可以表示出其他任意一个节点了,这样就可以实现我们的一些list的基本操作,
比如返回头结点(即返回node->next就可以了),返回尾结点(返回node本身就行了),返回头结点值,返回尾结点值,以及判空,返回长度
我们看一下在源码中是怎么实现的