C++之STL——list类

STL——list类

  • list简介
  • list的使用
    • list的构造函数
    • list的迭代器
    • list的capacity
    • list的元素提取
    • list的插入和删除
  • list的迭代器失效

list简介

1、list的插入和删除的时间复杂度是在常数范围内的序列式容器,并且由于list的底层是用双链表实现的,该容器支持双向迭代。
2、与其他序列式容器相比(array,vector,deque),list在任意位置进行插入和删除的效率更高。
3、list最大的缺陷就是不支持任意位置的随机访问。
C++之STL——list类_第1张图片

list的使用

list的构造函数

构造函数 接口说明
list() 构造空的list
list (size_type n, const value_type& val = value_type()) 构造的list中包含n个值为val的元素
list (const list& x) 拷贝构造
list (InputIterator first, InputIterator last) 使用迭代器构造

C++之STL——list类_第2张图片
C++之STL——list类_第3张图片

list的迭代器

在vector中,由于vector的底层是用连续空间进行存储的,因此原生指针就可以作为迭代器使用;但是list的底层是非连续空间,原生指针无法再作为迭代器,因此list的迭代器是通过模板封装实现的,这部分的底层原理放在下一篇博客模拟实现时进行详细解释。

迭代器 接口说明
begin() + end() 返回第一个元素的迭代器和返回最后一个元素的迭代器
rbegin() + rend() 返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的reverse_iterator,即begin位置

从图中可以看出,begin()是指向头节点的下一个节点,end()是指向头节点的。
C++之STL——list类_第4张图片
在这里插入图片描述
在这里插入图片描述

list的capacity

capacity 接口说明
capacity() 检测list是否为空,是返回true,否则返回false
size() 返回list中的有效节点个数

由于list的空间不是连续的,在使用时即插即用,因此list的底层没有改变空间和改变有效长度的函数reserve和resize。

list的元素提取

element access 接口说明
front() 返回list中第一个节点中的值
back() 返回list中最后一个节点中的值

C++之STL——list类_第5张图片
在这里插入图片描述

list的插入和删除

插入删除 接口说明
push_front 在list的第一个元素之前插入
pop_front 删除list中的第一个元素
push_back 在list的最后一个元素之后插入
pop_back 删除list中的最后一个元素
insert 在list的pos位置插入
erase 删除list的pos位置的元素
clear 清除list中的有效元素
list<int> v1;
  v1.push_back(1);
  v1.push_back(2);
  v1.push_back(3);
  v1.push_back(4);
  v1.push_back(5);
  v1.push_back(6);
  cout << "push_back(): ";
  for(auto e : v1)
    cout << e << " ";
  cout << endl;
  v1.push_front(10);
  v1.push_front(12);
  v1.push_front(13);
  cout << "push_front(): ";
  for(auto e : v1)
    cout << e << " ";
  cout << endl;
  v1.pop_back();
  v1.pop_back();
  cout << "pop_back(): ";
  for(auto e : v1)
    cout << e << " ";
  cout << endl;
  v1.pop_front();
  v1.pop_front();
  cout << "pop_front(): ";
  for(auto e : v1)
    cout << e << " ";
  cout << endl;
  list<int>::iterator pos = find(v1.begin(), v1.end(), 3);
  v1.insert(pos, 100);

  cout << "insert(): ";
  for(auto e : v1)
    cout << e << " ";
  cout << endl;

  
  pos = find(v1.begin(), v1.end(), 4);
  v1.erase(pos);

  cout << "erase(): ";
  for(auto e : v1)
    cout << e << " ";
  cout << endl;

C++之STL——list类_第6张图片

list的迭代器失效

在前面的stl容器中已经介绍过了迭代器失效的问题,这里的迭代器可以理解为指针,迭代器失效指的是迭代器所指向的节点无效,即该节点所指向的空间被释放了或者已经无意义了,如果此时还在该节点的迭代器进行操作就会出现错误。list的底层是带头节点的双向循环链表,因此在list中进行插入的时候不会导致迭代器的失效,只有在删除的时候才会失效,因为list的删除是释放该节点,此时对应的迭代器指向的空间是无效的。
这里还要注意一点,失效的只是被删除节点的迭代器,不会影响其他节点的迭代器。

C++之STL——list类_第7张图片
例如上面这段代码,目的是像想删除list中的所有元素,但是在删除之前没有保留当前元素的下一个节点的位置,在删除之后进行加一就会导致野指针的访问,这是典型的迭代器失效。在这里插入图片描述
因此想要防止迭代器失效,就需要在删除节点之前,将该节点的下一个位置保存下来,及时更新迭代器。
C++之STL——list类_第8张图片

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