C++ 入门15:STL 容器之列表(list)

往期回顾:

C++ 入门12:模板(Template)-CSDN博客

C++ 入门13:异常处理-CSDN博客

C++ 入门14:STL 容器之向量(vector)-CSDN博客


C++ 入门15:STL 容器之列表(list)

一、前言

在前面文章的学习中,我们学习了C++标准模板库(STL)中强大且灵活的向量容器。今天,我们将继续学习另一种常用的容器------列表(list)。列表是一种双向链表,与向量不同,它在插入和删除元素时效率更高,尤其适合需要频繁进行这类操作的场景。

二、STL 容器之列表(list)

2.1什么是列表?

列表(list)是C++ STL提供的另一种容器,它内部实现为双向链表。与向量相比,列表在元素的插入和删除操作上更为高效,因为这些操作通常只需要调整链表中相关节点的指针即可完成,而无需移动大量元素。

补充:双向链表结构

列表的核心在于其内部实现的双向链表。每个元素(或称为节点)在内存中不是连续存储的,而是每个节点包含两部分信息:一部分是存储的数据,另一部分是指向前一个节点和后一个节点的指针(或引用)。这种结构允许列表在任意位置快速地进行元素的插入和删除,而无需像向量那样可能需要移动大量元素来保持元素的连续性。

2.2、列表的基本操作

引入头文件 在使用列表之前,需要引入头文件 <list>。

(1)创建列表

列表的创建类似于向量,可以创建空列表或带有初始值的列表。

#include <iostream>
#include <list>
using namespace std;

int main() {
    list<int> lst1; // 创建一个空列表
    list<int> lst2(10, 5); // 创建一个包含10个元素的列表,每个元素的值为5
    list<int> lst3 = {1, 2, 3, 4, 5}; // 使用列表初始化
    return 0;
}

(2)添加元素

列表提供了 push_frontpush_back 方法来分别在列表的头部和尾部添加元素。

list<int> lst;
lst.push_front(10);
lst.push_back(20);
lst.push_front(5);

(3)访问元素

由于列表是链表结构,直接随机访问元素不如向量那样高效。不过,你可以通过迭代器或 front()back() 成员函数来访问首尾元素。

cout << "Front element: " << lst.front() << endl;
cout << "Back element: " << lst.back() << endl;

(4)删除元素

列表的 pop_frontpop_back 方法可以删除列表的首尾元素。此外,使用 erase 方法可以从列表中删除任何位置的元素。

lst.pop_front();
lst.pop_back();

(5)遍历列表

与向量类似,列表也提供了迭代器来遍历其元素。

for (list<int>::iterator it = lst.begin(); it != lst.end(); ++it) {
    cout << "Element: " << *it << endl;
}

或使用范围循环(C++11及以后版本):

for (int val : lst) {
    cout << "Element: " << val << endl;
}

尽管列表在插入和删除操作上表现出色,但在随机访问元素方面却不如向量高效。由于列表的元素是分散存储的,访问特定位置的元素需要从头或尾开始遍历链表,直到找到所需元素,这通常是一个线性时间复杂度(O(n))的操作。相比之下,向量可以直接通过下标在常数时间内访问任何位置的元素。

补充:插入与删除操作的高效性

  1. 插入操作:当在列表的某个位置插入新元素时,程序会创建一个新的节点,并调整该节点及其相邻节点的指针,以正确地将新节点链接到链表中。这个过程通常只需要常数时间(O(1)),前提是已经找到了插入点。与向量相比,向量在中部或前部插入元素时可能需要移动大量元素来为新元素腾出空间,这通常是一个线性时间复杂度(O(n))的操作。

  2. 删除操作:类似地,从列表中删除元素时,程序会找到待删除节点的前一个节点和后一个节点,并将这两个节点直接连接起来,从而绕过待删除的节点。随后,可能会释放被删除节点的内存。这个过程同样可以在常数时间内完成,而向量删除元素时也可能需要移动大量元素来填补空缺。

2.3、列表的高级操作

(1)反转列表

使用 reverse 方法可以轻松反转列表的顺序。

lst.reverse();

(2)排序列表

使用 sort 方法对列表进行排序。

lst.sort();

(3)合并两个列表

使用 splice 方法可以将另一个列表的元素合并到当前列表的指定位置。

list<int> lst2 = {6, 7, 8};
lst.splice(lst.end(), lst2);

(4)列表与向量的比较

尽管列表和向量都是STL容器,但它们在性能和使用场景上有所不同:

|------------|-----------------------------------|
| 插入和删除: | 列表在插入和删除元素时比向量更高效,尤其是当操作发生在列表中间时。 |
| 随机访问: | 向量提供了快速的随机访问,而列表在随机访问方面相对较慢。 |


以上就是 C++ 标准模板库中的列表(list)的基础知识点了。它是一种双向链表,特别适合需要频繁插入和删除元素的应用场景。掌握列表的使用,基本上在开发中都会用到的,大家多看看,一定要掌握。

都看到这里了,点个赞再走呗朋友~

加油吧,预祝大家变得更强!

相关推荐
XiaoLeisj2 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
dayouziei2 小时前
java的类加载机制的学习
java·学习
励志成为嵌入式工程师3 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉3 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer3 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq3 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
记录成长java5 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
前端青山5 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
青花瓷5 小时前
C++__XCode工程中Debug版本库向Release版本库的切换
c++·xcode
睡觉谁叫~~~5 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust