【C++初阶学习】C++list的使用及模拟(1)

简介: 【C++初阶学习】C++list的使用及模拟(1)

零、前言


本章主要讲解C++中的容器list的使用以及模拟实现


一、什么是list


  • list的介绍:


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


list与forward_list(单链表)的操作非常相似,但单链表只能朝前迭代


优劣:

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


对于链表与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问(不是连续开辟的动态空间)


示图:



image.png



二、list的常用接口说明


注:以下为list中一些常见的重要接口


1、list对象常用构造


image.png


  • 使用示例:


void test_list1()
{
  list<int> l1; // 构造空的l1
  list<int> l2(4, 100); // l2中放4个值为100的元素
  list<int> l3(l2.begin(), l2.end()); // 用l2的[begin(), end())左闭右开的区间构
  list<int> l4(l3); // 用l3拷贝构造l4
  // 以数组为迭代器区间构造l5
  int array[] = { 16,2,77,29 };
  list<int> l5(array, array + sizeof(array) / sizeof(int));
  // 用迭代器方式打印list中的元素
  for (list<int>::iterator it = l2.begin(); it != l2.end(); it++)
    cout << *it << " ";
  cout << endl;
  for (list<int>::iterator it = l4.begin(); it != l4.end(); it++)
    cout << *it << " ";
  cout << endl;
  // C++11范围for的方式遍历
  for (auto& e : l5)
    cout << e << " ";
  cout << endl;
}



image.png


2、list对象属性及迭代器使用


image.png


  • 迭代器示图:


image.png


注意:

begin与end为正向迭代器,对迭代器执行**++**操作,迭代器向后移动


**rbegin(end)与rend(begin)为反向迭代器,对迭代器执行++**操作,迭代器向前移动


list的迭代器并不是原生指针,而是经过封装的指针(后续模拟会提及)


使用示例:


void print_list(const list<int>& l)
{
  // 注意这里调用的是list的 begin() const,返回list的const_iterator对象
  for (list<int>::const_iterator it = l.begin(); it != l.end(); ++it)
  {
    cout << *it << " ";
    // *it = 10; 编译不通过(const迭代器不能修改指向内容)
  }
  cout << endl;
}
void test_list2()
{
  int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
  list<int> l(array, array + sizeof(array) / sizeof(array[0]));
  // 使用正向迭代器正向list中的元素
  for (list<int>::iterator it = l.begin(); it != l.end(); ++it)
    cout << *it << " ";
  cout << endl;
  // 使用反向迭代器逆向打印list中的元素
  for (list<int>::reverse_iterator it = l.rbegin(); it != l.rend(); ++it)
    cout << *it << " ";
  cout << endl;
  cout << l.size() << endl;
  cout << l.empty() << endl;
  cout << l.front() << endl;
  cout << l.back() << endl;
}


image.png


3、list对象修改操作


image.png


  • 使用示例:


void PrintList(list<int>& l)
{
  for (auto& e : l)
    cout << e << " ";
  cout << endl;
}
void test_list3()
{
  //push_back/pop_back/push_front/pop_front
  int array[] = { 1, 2, 3 };
  list<int> L(array, array + sizeof(array) / sizeof(array[0]));
  // 在list的尾部插入4,头部插入0
  L.push_back(4);
  L.push_front(0);
  PrintList(L);
  // 删除list尾部节点和头部节点
  L.pop_back();
  L.pop_front();
  PrintList(L);
  //insert/erase
  int array1[] = { 4,5,6 };
  list<int> L1(array1, array1 + sizeof(array1) / sizeof(array1[0]));
  // 获取链表中第二个节点
  auto pos = ++L1.begin();
  cout << *pos << endl;
  // 在pos前插入值为4的元素
  L1.insert(pos, 4);
  PrintList(L1);
  // 在pos前插入5个值为5的元素
  L1.insert(pos, 5, 5);
  PrintList(L1);
  // 在pos前插入[v.begin(), v.end)区间中的元素
  vector<int> v{ 7, 8, 9 };
  L1.insert(pos, v.begin(), v.end());
  PrintList(L1);
  // 删除pos位置上的元素
  L1.erase(pos);
  PrintList(L1);
  // 删除list中[begin, end)区间中的元素,即删除list中的所有元素
  L1.erase(L1.begin(), L1.end());
  PrintList(L1);
  //resize/swap/clear
  // 用数组来构造list
  int array2[] = { 7,8,9 };
  list<int> l2(array1, array1 + sizeof(array1) / sizeof(array1[0]));
  PrintList(l2);
  // 交换l1和l2中的元素
  L1.swap(l2);
  PrintList(L1);
  PrintList(l2);
  // 将l2中的元素清空
  l2.clear();
  cout << l2.size() << endl;
}


image.png

相关文章
|
2天前
|
C++ 容器
|
4天前
|
调度 C++ 容器
【C++】手搓 list 容器
本文我们实现了STL库中重要的list 的模拟实现,其中最重要莫过于迭代器的封装类的书写,这是前所未有的操作(对于我来说,我是第一次使用这种结构)。通过list 的模拟实现也帮我们巩固了类与对象的知识,也强化了指针操作的思路。欢迎大家讨论分析。
13 1
|
4天前
|
编译器 C++
【C++】继续学习 string类 吧
首先不得不说的是由于历史原因,string的接口多达130多个,简直冗杂… 所以学习过程中,我们只需要选取常用的,好用的来进行使用即可(有种垃圾堆里翻美食的感觉)
9 1
|
4天前
|
算法 安全 程序员
【C++】STL学习之旅——初识STL,认识string类
现在我正式开始学习STL,这让我期待好久了,一想到不用手撕链表,手搓堆栈,心里非常爽
16 0
|
4天前
|
存储 安全 测试技术
【C++】string学习 — 手搓string类项目
C++ 的 string 类是 C++ 标准库中提供的一个用于处理字符串的类。它在 C++ 的历史中扮演了重要的角色,为字符串处理提供了更加方便、高效的方法。
18 0
【C++】string学习 — 手搓string类项目
|
4天前
|
存储 编译器 C++
【C++/STL】list(常见接口、模拟实现、反向迭代器、)
【C++/STL】list(常见接口、模拟实现、反向迭代器、)
5 0
|
4天前
|
编译器 C语言 C++
c++初阶------类和对象(六大默认构造函数的揭破)-3
c++初阶------类和对象(六大默认构造函数的揭破)
|
4天前
|
编译器 C语言 C++
c++初阶------类和对象(六大默认构造函数的揭破)-2
c++初阶------类和对象(六大默认构造函数的揭破)
|
4天前
|
存储 编译器 C语言
c++初阶-------类和对象-2
c++初阶-------类和对象
|
4天前
|
安全 编译器 C语言
C++初阶------------------入门C++(三)
C++初阶------------------入门C++(三)