一、list 的核心特性
list 是一个双向链表 (doubly linked list),这是它区别于vector(动态数组)的核心:
- 底层结构:每个元素都有前驱和后继指针,元素在内存中不连续存储
- 优势:任意位置的插入 / 删除操作效率极高(O (1)),无需移动其他元素
- 劣势:不支持随机访问(无法用下标
[]访问),只能通过迭代器遍历,访问元素效率低(O (n)) - 额外开销:每个元素需要存储前驱 / 后继指针,内存开销比
vector大
二、list 的基本用法(完整代码示例)
cpp
运行
#include <iostream>
#include <list> // 必须包含list头文件
#include <algorithm> // 用于sort、find等算法
using namespace std;
int main() {
// 1. 创建list容器
list<int> myList; // 空的int类型list
list<int> list2(5, 10); // 初始化5个元素,每个值为10
list<int> list3 = {1, 3, 5, 2, 4}; // 初始化列表(C++11及以上)
// 2. 插入元素(list的核心优势:任意位置高效插入)
myList.push_back(10); // 尾部插入
myList.push_front(20); // 头部插入
// 在指定位置插入(需先获取迭代器)
auto it = myList.begin(); // 指向第一个元素(20)的迭代器
myList.insert(++it, 30); // 在20和10之间插入30,此时list:20 → 30 → 10
// 3. 访问元素(不支持[]和at,只能用迭代器/front/back)
cout << "第一个元素:" << myList.front() << endl; // 20
cout << "最后一个元素:" << myList.back() << endl; // 10
// 4. 遍历list(三种常见方式)
cout << "\n方式1:迭代器遍历:";
for (list<int>::iterator it = myList.begin(); it != myList.end(); ++it) {
cout << *it << " ";
}
cout << "\n方式2:范围for遍历:";
for (int num : myList) {
cout << num << " ";
}
cout << "\n方式3:反向遍历:";
for (list<int>::reverse_iterator it = myList.rbegin(); it != myList.rend(); ++it) {
cout << *it << " ";
}
// 5. 删除元素(同样支持任意位置高效删除)
myList.pop_front(); // 删除头部元素(20)
myList.pop_back(); // 删除尾部元素(10)
cout << "\n删除头尾后:";
for (int num : myList) cout << num << " "; // 只剩30
// 6. list专属操作(区别于其他容器)
list3.sort(); // 链表自带排序(vector用std::sort,list不能用)
cout << "\n排序后的list3:";
for (int num : list3) cout << num << " "; // 1 2 3 4 5
list3.remove(3); // 删除所有值为3的元素
cout << "\n删除值为3后:";
for (int num : list3) cout << num << " "; // 1 2 4 5
list3.unique(); // 删除连续重复元素(需先排序才会生效)
myList.clear(); // 清空容器
cout << "\n清空后是否为空:" << (myList.empty() ? "是" : "否") << endl;
return 0;
}
输出结果:
plaintext
第一个元素:20
最后一个元素:10
方式1:迭代器遍历:20 30 10
方式2:范围for遍历:20 30 10
方式3:反向遍历:10 30 20
删除头尾后:30
排序后的list3:1 2 3 4 5
删除值为3后:1 2 4 5
清空后是否为空:是
三、list 的关键注意事项
-
迭代器特性 :
- list 的迭代器是双向迭代器 (只能 ++/--),不是随机访问迭代器,因此:
- 不能用
it + 5这种随机跳转操作,只能++it逐步移动 - 不能直接用
std::sort排序,必须用list.sort()成员函数
- 不能用
- list 的迭代器是双向迭代器 (只能 ++/--),不是随机访问迭代器,因此:
-
插入 / 删除不失效迭代器 :
- 对 list 插入 / 删除元素时,除了指向被删除元素的迭代器,其他迭代器都不会失效(vector 插入可能导致迭代器全部失效)
-
常用成员函数 :
函数 作用 sort()对链表元素升序排序 remove(val)删除所有值为 val 的元素 unique()删除连续重复的元素 reverse()反转链表元素顺序 splice()拼接两个 list(高效移动)
四、list vs vector 选型对比
| 场景 | 选 vector | 选 list |
|---|---|---|
| 随机访问(按下标取值) | ✅ | ❌ |
| 尾部增删元素 | ✅ | ✅ |
| 中间 / 头部频繁增删元素 | ❌ | ✅ |
| 内存连续性(需兼容 C 数组) | ✅ | ❌ |
| 内存开销(少指针) | ✅ | ❌ |
总结
list是双向链表结构,核心优势是任意位置的插入 / 删除操作效率极高 ,核心劣势是不支持随机访问。list有专属的操作函数(如sort()、remove()),不能直接使用std::sort等依赖随机访问迭代器的算法。- 选型时,若业务场景以 "中间 / 头部频繁增删" 为主,选
list;若以 "随机访问、尾部增删" 为主,选vector。