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

0 阅读3分钟

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 容器一致
#include <list>
  • 初始化
// 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() 访问首尾元素,其他元素需迭代器遍历:

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)


	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 清空)

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 仅支持双向迭代器(不能随机移动,只能 ++/--),遍历方式如下:

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;
	
	});