文章目录
前言
一个梦想与一个坚定不移的意志
一、list的介绍
- list 可以在常数范围内任意位置进行插入和删除的容器,并且可以双向迭代
- list 在底层是双向循环链表的结构。
- list 与其它容器(如string, vector)相比,最大的缺点是不支持随机访问,比如:要访问list的第5个元素时,不能像vector一样用 [ ] 取下标直接访问,而是要从头节点迭代到该位置。
二、引入——构造方式,遍历方式
#include <iostream>
#include <list>
using namespace std;
int main()
{
list<int> L1; //使用了无参构造
list<int> L2(5,5); //L2(n,elm)用n个elm构造
int a[5] = {
1,2,3,4,5};
list L3(a,a+5);
list L4(L3);
L1.push_back(2);
L1.push_back(3);
L1.push_back(4);
list<int>::iterator it = L1.begin();
//遍历方式1
for(; it != L1.end(); it++)
{
cout<<*it<<"";
}
cout<<endl;
//遍历方式2
//这种方式C++11支持
for(auto e : it)
{
cout<<e<<" "
}
cout<<endl;
return 0;
}
1. 代码观察
(1)我们对L1使用了使用了无参构造,对L2使用了n个相同元素构造,对L3使用了迭代器区间构造,对L4使用了拷贝构造。
(2)遍历方式1中我们使用的是it != L1.end()。
2. 我的疑问
(1)使用指针代替的迭代器用来构造,这可行吗?
(2)!=是否可以改为<=?
3. 解答
(1)原生指针可以当作天然迭代器使用,其实vector/string的迭代器就是原生指针
(2)不可以,因为list中的数据不是连续存储的。
4. 拓展
(1)常见的容器的迭代器
1.单向:++ forword_list
2.双向:++/-- list (不支持+=,-=)
3 随机: ++/--/+/- vector (物理上是连续的)
(2)sort排序
1.list在自己类中实现了一个sort,而当我们使用算法库中的sort时,会产生错误
2.因为sort底层使用的是快速排序,快排要求容器是随机迭代器,效率会降低。比如:使用三数取中的优化时,因为不能随机访问,导致会遍历一边数据,效率降低,所以就不会使用算法库中的sort,而是类中实现了一个。
三、迭代器失效的问题
通常迭代器失效有俩个原因
(1)插入后,迭代器所指向的位置意义变了,这在vector中经常遇到。
(2)删除后,迭代器所指向的空间被释放了。
而因为List的底层是双向循环链表,因此在list中插入时不会使迭代器失效,只有在删除时才会失效。
四、C++简单模拟实现list
1. 节点类的创建
template<class T>
struct _list_node
{
_list_node(const T& val = T())//调用了val的无参构造,无论是内置类型还是自定义类型均可以初始化
:_val(val)
,_next(nullptr)
,_prev(nullptr)
{
}
T _val