std::list 是一个双向链表容器,支持高效的插入和删除操作(尤其是在链表中间位置),但不支持随机访问。
一、基础用法
1. 头文件与命名空间
#include <list> // 必须包含的头文件
using namespace std; // 或显式使用 std::list
2. 定义与初始化
// 定义空 list
list<int> lst1; // 存储 int 类型的空链表
// 初始化为 n 个值为 val 的元素
list<int> lst2(5, 10); // 5 个元素,每个都是 10 → [10,10,10,10,10]
// 用初始化列表初始化(C++11+)
list<int> lst3 = {1, 2, 3, 4}; // 直接初始化元素 → [1,2,3,4]
// 复制另一个 list
list<int> lst4(lst3); // 复制 lst3 的内容 → [1,2,3,4]
list<int> lst5 = lst3; // 同上
二、常用成员函数
1. 元素访问(无随机访问,只能通过首尾或迭代器)
| 函数 |
功能说明 |
示例 |
| front() |
返回第一个元素的引用 |
int first = lst.front(); |
| back() |
返回最后一个元素的引用 |
int last = lst.back(); |
2. 容量与大小
| 函数 |
功能说明 |
示例 |
| size() |
返回当前元素个数 |
int len = lst.size(); |
| empty() |
判断容器是否为空 |
(size() == 0) if (lst.empty()) |
| resize(n, val) |
调整容器大小为 n,新增元素用 val 填充 |
lst.resize(5, 0); // 大小调整为 5 |
3. 元素修改(list 的核心优势:高效插入删除)
| 函数 |
功能说明 |
示例 |
| push_back(val) |
在尾部添加元素 |
lst.push_back(5); |
| pop_back() |
删除尾部元素(不返回值) |
lst.pop_back(); |
| push_front(val) |
在头部添加元素(list 特有,vector 无) |
lst.push_front(0); |
| pop_front() |
删除头部元素(list 特有) |
lst.pop_front(); |
| insert(pos, val) |
在迭代器 pos 位置插入 val(时间复杂度 O (1)) |
lst.insert(it, 10); //it 是迭代器 |
| insert(pos, n, val) |
在 pos 位置插入 n 个 val |
lst.insert(it, 3, 20); |
| erase(pos) |
删除迭代器 pos 位置的元素 |
lst.erase(it); |
| erase(beg, end) |
删除 [beg, end) 范围内的元素 |
lst.erase(beg, end); |
| clear() |
清空所有元素(size() 变为 0) |
lst.clear(); |
| swap(lst2) |
与另一个 list 交换内容 |
lst.swap(lst2); |
| splice(pos, lst2) |
将 lst2 的所有元素移动到 pos 位置(不复制,直接转移节点) |
lst.splice(it, lst2); |
4. 迭代器(必须通过迭代器遍历,无下标访问)
| 函数 |
功能说明 |
示例 |
| begin() / end() |
正向迭代器(指向首元素 / 尾后位置) |
for (auto it = lst.begin(); it != lst.end(); ++it) |
| rbegin() / rend() |
反向迭代器(指向尾元素 / 首前位置) |
for (auto it = lst.rbegin(); it != lst.rend(); ++it) |
5. 其他常用函数
| 函数 |
功能说明 |
示例 |
| sort() |
对元素进行排序(默认升序) |
lst.sort(); |
| sort(cmp) |
自定义排序规则(传入比较函数) |
lst.sort(greater()); // 降序 |
| reverse() |
反转链表中的元素顺序 |
lst.reverse(); |
| unique() |
移除连续的重复元素(需先排序) |
lst.sort(); lst.unique(); |
| merge(lst2) |
合并两个已排序的链表(合并后仍有序) |
lst1.merge(lst2); |
三、遍历 list 的方式(只能通过迭代器或范围 for)
list<int> lst = {1, 2, 3, 4, 5};
// 1. 正向迭代器遍历
for (list<int>::iterator it = lst.begin(); it != lst.end(); ++it) {
cout << *it << " "; // 输出:1 2 3 4 5
}
// 2. 反向迭代器遍历
for (list<int>::reverse_iterator it = lst.rbegin(); it != lst.rend(); ++it) {
cout << *it << " "; // 输出:5 4 3 2 1
}
// 3. 范围 for 循环(C++11+)
for (int x : lst) {
cout << x << " "; // 输出:1 2 3 4 5
}
四、list 与 vector 的核心区别
| 特性 |
std::list |
std::vector |
| 数据结构 |
双向链表(节点存储数据,通过指针连接) |
动态数组(连续内存空间) |
| 随机访问 |
不支持([] 和 at() 不可用) |
支持(O(1) 时间复杂度) |
| 插入 / 删除(中间) |
高效(O(1),只需修改指针) |
低效(O(n),需移动后续元素) |
| 插入 / 删除(首尾) |
头部插入 O(1),尾部插入 O(1) |
尾部插入 O(1)(可能扩容),头部插入 O(n) |
| 内存连续性 |
不连续(节点分散存储) |
连续(可直接访问底层数组) |
| 迭代器稳定性 |
插入 / 删除元素后,其他迭代器仍有效 |
扩容后迭代器失效,删除中间元素后后续迭代器失效 |
示例:综合使用 list
#include <iostream>
#include <list>
#include <algorithm> // 用于 greater 排序
using namespace std;
int main() {
list<int> lst = {3, 1, 4, 2};
// 在头部和尾部添加元素
lst.push_front(0); // → [0,3,1,4,2]
lst.push_back(5); // → [0,3,1,4,2,5]
// 插入元素到中间(通过迭代器定位)
auto it = lst.begin();
advance(it, 2); // 移动迭代器到索引2的位置(值为1)
lst.insert(it, 100); // → [0,3,100,1,4,2,5]
// 排序(升序)
lst.sort(); // → [0,1,2,3,4,5,100]
// 反转
lst.reverse(); // → [100,5,4,3,2,1,0]
// 遍历输出
cout << "元素: ";
for (int x : lst) {
cout << x << " "; // 输出:100 5 4 3 2 1 0
}
// 删除第一个和最后一个元素
lst.pop_front(); // → [5,4,3,2,1,0]
lst.pop_back(); // → [5,4,3,2,1]
cout << "\n最终大小: " << lst.size() << endl; // 输出:5
return 0;
}