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两端操作不失效但中间操作失效)。
- 任意位置插入 / 删除:时间复杂度 O(1)(只需修改指针,无需移动元素,远优于
- 缺点
- 无随机访问:无法用
[]/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;
});