【C++】STL —— list的基本使用

简介: 【C++】STL —— list的基本使用

一、list容器的简介


1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。

2. list的底层是 双向链表结构 ,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。

3. list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效。

4. 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。

5. 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素)

1ecd1b2606ed46e9956a89f231c9802c.png

二、list容器常用的接口

1.list初始化操作

1.构造函数

1ecd1b2606ed46e9956a89f231c9802c.png

void test_list1()
{
  list<int> lt1;        //构造一个空list
  list<int> lt2(5, 10); //构造5个节点list,每个结点的元素是10
  list<int> lt3(lt2.begin(), lt2.end()); //用lt2的迭代器区间构造lt3
  list<int> lt5(lt3);   //用lt3去拷贝构造出lt5
}

2.析构函数

1ecd1b2606ed46e9956a89f231c9802c.png

3.赋值重载函数

1ecd1b2606ed46e9956a89f231c9802c.png

void test_list2()
{
  list<int> lt1(6, 8);
  for (auto e : lt1)
  {
    cout << e << " ";// lt1:8 8 8 8 8 8
  }
  cout << endl;
  list<int> lt2(5, 10);
  lt1 = lt2;
  for (auto e : lt1)
  {
    cout << e << " ";// lt1:10 10 10 10 10
  }
  cout << endl;
}

2.list容量相关的函数

1ecd1b2606ed46e9956a89f231c9802c.png

函数名 功能
empty 测试容器是否为空
size 返回容器中的元素数量
max_size 返回列表容器所能容纳的最大元素数
void test_list3()
{
  list<int> lt1(6, 8);            //用6个8对lt1进行初始化
  cout << lt1.empty() << endl;    //判断容器是否为空
  cout << lt1.size() << endl;     //计算出容器中的元素数量
  cout << lt1.max_size() << endl; //列表容器所能容纳的最大元素数
}

3.list的迭代器

       list也支持迭代器,就想数组一样,从第一个元素访问到下一个元素,但是list的迭代器在实现上和之前的string、vector却有所不同,在下篇博客中会进行模拟实现。深入的了解list迭代器的原理。

1ecd1b2606ed46e9956a89f231c9802c.png

函数名 功能
begin 返回起始位置的迭代器(第一个元素)
end 返回的是头结点地址
rbegin 返回的是头结点地址
rend 返回起始位置的迭代器(第一个元素)


对于这里迭代器的功能,需要在后面的模拟实现中才能很好的理解。目前只需要了解其使用方法。

void test_list4()
{
  list<int> lt1;    //构建一个空的lt1
  lt1.push_back(1);
  lt1.push_back(2);
  lt1.push_back(3);
  lt1.push_back(4); //尾插 1 2 3 4
  list<int>::iterator it = lt1.begin(); //获取双向链表起始位置的迭代器(正向)
  while (it != lt1.end()) 
  {
    cout << *it << " "; //打印数据
    ++it;
  }
  cout << endl;
  list<int>::reverse_iterator rit = lt1.rbegin(); //获取双向链表起始位置的迭代器(反向)
  while (rit != lt1.rend())
  {
    cout << *rit << " "; //打印数据
    ++rit;
  }
  cout << endl;
}

4.list的增删查改

1ecd1b2606ed46e9956a89f231c9802c.png

image.png

列举一些常用的函数,其他的可以了解一下

void test_list5()
{
  list<int> lt1;
  lt1.push_back(1);
  lt1.push_back(2);
  lt1.push_back(3);
  lt1.push_back(4); //尾插 1 2 3 4
  lt1.push_front(10);
  lt1.push_front(20);
  lt1.push_front(30);
  lt1.push_front(40); //头插 1 2 3 4
  lt1.pop_back();  //尾删
  lt1.pop_front(); //头删 
  list<int>::iterator pos = find(lt1.begin(), lt1.end(), 20);//查找20所在的位置
  if (pos != lt1.end())
  {
    pos = lt1.insert(pos, 88); //在pos位置插入88,并将新的迭代器返还给pos
  }
  lt1.erase(pos); //删除pos位置的88
  for (auto e : lt1) //通过范围for打印数据
  {
    cout << e << " ";
  }
  cout << endl;
  lt1.clear(); //清空数据
}




目录
相关文章
|
4天前
|
C++ 容器
|
4天前
|
存储 算法 搜索推荐
C++|STL简介-string-vector基础运用
C++|STL简介-string-vector基础运用
|
6天前
|
设计模式 算法 C++
【C++】STL之迭代器介绍、原理、失效
【C++】STL之迭代器介绍、原理、失效
13 2
|
6天前
|
存储 C++ 容器
C++:STL - set & map
C++:STL - set & map
16 4
|
6天前
|
调度 C++ 容器
【C++】手搓 list 容器
本文我们实现了STL库中重要的list 的模拟实现,其中最重要莫过于迭代器的封装类的书写,这是前所未有的操作(对于我来说,我是第一次使用这种结构)。通过list 的模拟实现也帮我们巩固了类与对象的知识,也强化了指针操作的思路。欢迎大家讨论分析。
14 1
|
6天前
|
算法 安全 程序员
【C++】STL学习之旅——初识STL,认识string类
现在我正式开始学习STL,这让我期待好久了,一想到不用手撕链表,手搓堆栈,心里非常爽
17 0
|
6天前
|
存储 Serverless C++
【C++入门到精通】哈希 (STL) _ unordered_map _ unordered_set [ C++入门 ]
【C++入门到精通】哈希 (STL) _ unordered_map _ unordered_set [ C++入门 ]
11 1
|
6天前
|
存储 设计模式 算法
【C++/STL】stack和queue(容器适配器、优先队列、双端队列)
【C++/STL】stack和queue(容器适配器、优先队列、双端队列)
16 1
|
6天前
|
存储 编译器 C++
【C++/STL】list(常见接口、模拟实现、反向迭代器、)
【C++/STL】list(常见接口、模拟实现、反向迭代器、)
5 0
|
1天前
|
C++
【C++基础】类class
【C++基础】类class
9 1