【C++ STL】list容器的基本使用

List容器

list 是 C++ STL 中的双向链表容器,定义在 <list> 头文件中。它的核心特征是非连续内存存储,每个节点包含数据和指向前后节点的指针,因此擅长任意位置的高效插入 / 删除,但不支持随机访问。list 是对 vector/deque 的重要补充,适合频繁修改元素位置的场景。

  • 底层结构:双向链表(每个节点 = 数据 + prev 指针 + next 指针),无中控数组 / 连续内存,节点分散在内存中。
  • 优点
    • 任意位置插入 / 删除:时间复杂度 O(1)(只需修改指针,无需移动元素,远优于 vector/deque 的 O(n));
    • 两端操作:push_front/pop_front/push_back/pop_back 均为 O(1);
    • 迭代器稳定性:插入 / 删除元素后,除被删除节点的迭代器外,其他迭代器均不失效(vector 扩容后迭代器失效,deque 两端操作不失效但中间操作失效)。
  • 缺点
    • 无随机访问:无法用 []/at() 访问元素,只能通过迭代器遍历(访问第 n 个元素需 O(n) 时间);
    • 内存开销高:每个节点额外存储两个指针;
    • 不支持 STL 随机访问算法(如 sort 需用自身成员函数,而非 <algorithm> 中的 sort)。

基本使用

  • 使用 list 需包含 <list>,初始化方式与其他 STL 容器一致
c++ 复制代码
#include <list>
  • 初始化
c++ 复制代码
// 1、空初始化,默认构造函数
list<int> l1;

// 2、初始化指定数量和初始化值
list<int> l2(10, 100);

// 3、拷贝构造函数
list<int> l3(l2);

// 4、迭代器范围初始化
int arr[] = { 0, 1, 2, 3, 4 , 5 };
list<int> l4(arr, arr + 5);

// 5、列表初始化(c++ 11)
list<int> l5 = { 0, 1, 2, 3, 4, 5 };

核心操作API

元素访问,无随机访问

list 仅支持通过 front()/back() 访问首尾元素,其他元素需迭代器遍历:

c++ 复制代码
list<int> lst = { 0, 1, 2, 3, 4, 5 };

// 元素访问
cout << lst.front() << " " << lst.back() << endl;

插入/删除

list的插入/删除是核心优势,尤其是中间位置的操作:

操作 说明 时间复杂度
push_front(val) 头部插入元素 O(1)

push_back(val) 尾部插入元素O(1)

pop_front() 删除头部元素O(1)

pop_back() 删除尾部元素O(1)

insert(pos, val) 在迭代器 pos 位置插入 valO(1)

insert(pos, n, val) 在 pos 位置插入 n 个 valO(n)

erase(pos) 删除 pos 位置的元素O(1)

erase(begin, end) 删除 [begin, end) 范围的元素O(n)

remove(val)删除所有值为 val 的元素O(n)

clear()清空所有元素O(n)

emplace(pos, args...)原地构造元素(C++11,避免拷贝,更高效)O(1)

emplace_front(args...)头部原地构造元素O(1)

emplace_back(args...)尾部原地构造元素O(1)

c++ 复制代码
	list<int> lst = { 0, 1, 2, 3, 4, 5 };

	// 头部插入
	lst.push_front(100);
	// 尾部插入
	lst.push_back(500);


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

	// 删除头部元素
	lst.pop_front();

	// 删除尾部元素
	lst.pop_back();

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

	// 插入元素
	lst.insert(lst.begin(), 200);
	lst.insert(++lst.begin(), 2, 100);		// 在指定位置插入2个100

	// 删除元素
	lst.erase(--lst.end());

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

容量与其他操作

size()获取元素个数

empty()判断是否为空

resize(n, val)调整大小,不足补 val(默认 0)

reverse()反转链表(成员函数,O(n))

sort()排序(成员函数,O(nlogn),不支持 std::sort)

unique()去重(需先排序,删除连续重复元素)

merge(l2)合并两个已排序的 list(l2 会被清空)

splice(pos, l2)将 l2 所有元素插入到 pos 位置(l2 清空)

c++ 复制代码
list<int> lst = { 0, 1, 2, 3, 4, 5 };

// 排序,list必须使用对象方法
// 默认从小到大
lst.sort();

// 第一种方式大到小
lst.sort(greater<int>());

// 第二种方式
lst.sort([](int a, int b) {return a > b; });

遍历方式

list 仅支持双向迭代器(不能随机移动,只能 ++/--),遍历方式如下:

c++ 复制代码
list<int> lst = { 0, 1, 2, 3, 4, 5 };

// 迭代器
for (list<int>::iterator it = lst.begin(); it != lst.end(); it++)
{
	cout << *it << endl;
}

// C++ 11 增强for循环
for (int i : lst )
{
	cout << i << endl;
}

// for_each算法遍历
for_each(lst.begin(), lst.end(), [](int val) {
	
	cout << val << endl;
	
	});
相关推荐
博客18001 天前
酷宝的使用方法,超好用的免费界面库,C++、MFC可用
c++·mfc·界面库·库来帮·酷宝
郝学胜_神的一滴1 天前
CMake 026:属性体系精讲、四大作用域全解 & 实战代码落地
c++·cmake
众少成多积小致巨2 天前
JNI (Java Native Interface) 技术手册中文参考指南
android·java·c++
clint4566 天前
C++进阶(1)——前景提要
c++
夜悊6 天前
C++代码示例:进制数简单生成工具
c++
郝学胜_神的一滴6 天前
CMake 021: IF 条件判据详诠
c++·cmake
_wyt0017 天前
洛谷 B3930 [GESP202312 五级] 烹饪问题 题解
c++·gesp
LDR0067 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术7 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript
码云数智-园园7 天前
C++20 Modules 模块详解
java·开发语言·spring