【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(); //清空数据
}




目录
相关文章
|
22天前
|
编译器 C语言 C++
【c++丨STL】list模拟实现(附源码)
本文介绍了如何模拟实现C++中的`list`容器。`list`底层采用双向带头循环链表结构,相较于`vector`和`string`更为复杂。文章首先回顾了`list`的基本结构和常用接口,然后详细讲解了节点、迭代器及容器的实现过程。 最终,通过这些步骤,我们成功模拟实现了`list`容器的功能。文章最后提供了完整的代码实现,并简要总结了实现过程中的关键点。 如果你对双向链表或`list`的底层实现感兴趣,建议先掌握相关基础知识后再阅读本文,以便更好地理解内容。
26 1
|
1月前
|
算法 C语言 C++
【c++丨STL】list的使用
本文介绍了STL容器`list`的使用方法及其主要功能。`list`是一种双向链表结构,适用于频繁的插入和删除操作。文章详细讲解了`list`的构造函数、析构函数、赋值重载、迭代器、容量接口、元素访问接口、增删查改操作以及一些特有的操作接口如`splice`、`remove_if`、`unique`、`merge`、`sort`和`reverse`。通过示例代码,读者可以更好地理解如何使用这些接口。最后,作者总结了`list`的特点和适用场景,并预告了后续关于`list`模拟实现的文章。
51 7
|
1月前
|
存储 编译器 C++
C++ initializer_list&&类型推导
在 C++ 中,`initializer_list` 提供了一种方便的方式来初始化容器和传递参数,而右值引用则是实现高效资源管理和移动语义的关键特性。尽管在实际应用中 `initializer_list&&` 并不常见,但理解其类型推导和使用方式有助于深入掌握现代 C++ 的高级特性。
23 4
|
2月前
|
存储 编译器 C语言
【c++丨STL】vector的使用
本文介绍了C++ STL中的`vector`容器,包括其基本概念、主要接口及其使用方法。`vector`是一种动态数组,能够根据需要自动调整大小,提供了丰富的操作接口,如增删查改等。文章详细解释了`vector`的构造函数、赋值运算符、容量接口、迭代器接口、元素访问接口以及一些常用的增删操作函数。最后,还展示了如何使用`vector`创建字符串数组,体现了`vector`在实际编程中的灵活性和实用性。
96 4
|
2月前
|
C语言 C++ 容器
【c++丨STL】string模拟实现(附源码)
本文详细介绍了如何模拟实现C++ STL中的`string`类,包括其构造函数、拷贝构造、赋值重载、析构函数等基本功能,以及字符串的插入、删除、查找、比较等操作。文章还展示了如何实现输入输出流操作符,使自定义的`string`类能够方便地与`cin`和`cout`配合使用。通过这些实现,读者不仅能加深对`string`类的理解,还能提升对C++编程技巧的掌握。
101 5
|
2月前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
78 2
|
1月前
|
存储 编译器 C语言
【c++丨STL】vector模拟实现
本文深入探讨了 `vector` 的底层实现原理,并尝试模拟实现其结构及常用接口。首先介绍了 `vector` 的底层是动态顺序表,使用三个迭代器(指针)来维护数组,分别为 `start`、`finish` 和 `end_of_storage`。接着详细讲解了如何实现 `vector` 的各种构造函数、析构函数、容量接口、迭代器接口、插入和删除操作等。最后提供了完整的模拟实现代码,帮助读者更好地理解和掌握 `vector` 的实现细节。
46 0
|
11天前
|
C++ 芯片
【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
声明一个简单的Computer类,含有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,以及两个公有成员函数run、stop。只能在类的内部访问。这是一种数据隐藏的机制,用于保护类的数据不被外部随意修改。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。成员可以在派生类(继承该类的子类)中访问。成员,在类的外部不能直接访问。可以在类的外部直接访问。为了完成本关任务,你需要掌握。
51 18
|
11天前
|
存储 编译器 数据安全/隐私保护
【C++面向对象——类与对象】CPU类(头歌实践教学平台习题)【合集】
声明一个CPU类,包含等级(rank)、频率(frequency)、电压(voltage)等属性,以及两个公有成员函数run、stop。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。​ 相关知识 类的声明和使用。 类的声明和对象的声明。 构造函数和析构函数的执行。 一、类的声明和使用 1.类的声明基础 在C++中,类是创建对象的蓝图。类的声明定义了类的成员,包括数据成员(变量)和成员函数(方法)。一个简单的类声明示例如下: classMyClass{ public: int
37 13
|
11天前
|
编译器 数据安全/隐私保护 C++
【C++面向对象——继承与派生】派生类的应用(头歌实践教学平台习题)【合集】
本实验旨在学习类的继承关系、不同继承方式下的访问控制及利用虚基类解决二义性问题。主要内容包括: 1. **类的继承关系基础概念**:介绍继承的定义及声明派生类的语法。 2. **不同继承方式下对基类成员的访问控制**:详细说明`public`、`private`和`protected`继承方式对基类成员的访问权限影响。 3. **利用虚基类解决二义性问题**:解释多继承中可能出现的二义性及其解决方案——虚基类。 实验任务要求从`people`类派生出`student`、`teacher`、`graduate`和`TA`类,添加特定属性并测试这些类的功能。最终通过创建教师和助教实例,验证代码
37 5

热门文章

最新文章