C++STL库, 理解STL中的list

文章目录

  • 前言
    • 一个梦想与一个坚定不移的意志
  • 一、list的介绍
  • 二、引入——构造方式,遍历方式
    • 1. 代码观察
    • 2. 我的疑问
    • 3. 解答
    • 4. 拓展
      • (1)常见的容器的迭代器
      • (2)sort排序
  • 三、迭代器失效的问题
  • 四、C++简单模拟实现list
    • 1. 节点类的创建
    • 2.list的迭代器
      • (1)实现方式
      • (2)代码实现
        • <1>operator->()函数中编译器的优化行为
        • <2>三个模板参数问题
    • 3. list的实现
      • (1) 三个模板参数的问题


前言

一个梦想与一个坚定不移的意志

一、list的介绍

  1. list 可以在常数范围内任意位置进行插入和删除的容器,并且可以双向迭代
  2. list 在底层是双向循环链表的结构。
  3. list 与其它容器(如string, vector)相比,最大的缺点是不支持随机访问,比如:要访问list的第5个元素时,不能像vector一样用 [ ] 取下标直接访问,而是要从头节点迭代到该位置。

二、引入——构造方式,遍历方式

#include 
#include 
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

你可能感兴趣的:(c++,list)