C++中的list容器详解
1. list概述
list是C++ STL中的双向链表容器,支持在任何位置高效插入和删除元素。与vector和deque不同,list不提供随机访问能力,但提供了高效的插入和删除操作。
2. 基本特性
- 双向链表:每个元素包含指向前后元素的指针
- 高效插入/删除 :在任何位置插入/删除都是O(1)O(1)O(1)时间复杂度
- 无随机访问:不支持下标操作,必须通过迭代器遍历
- 不连续存储:元素分散在内存中
3. 头文件与声明
cpp
#include <list>
using namespace std;
list<int> lst1; // 空list
list<string> lst2(10); // 包含10个默认构造的string
list<double> lst3(5, 3.14); // 包含5个3.14
list<char> lst4 = {'a', 'b', 'c'}; // 初始化列表
4. 构造函数与初始化
4.1 默认构造
cpp
list<int> lst;
4.2 填充构造
cpp
list<int> lst(10); // 10个默认初始化的int(0)
list<int> lst(5, 100); // 5个100
4.3 范围构造
cpp
int arr[] = {1, 2, 3};
list<int> lst(arr, arr+3);
4.4 拷贝构造
cpp
list<int> lst2(lst1);
5. 容量操作
5.1 size()
cpp
cout << lst.size(); // 返回元素数量
5.2 empty()
cpp
if(lst.empty()) {
cout << "List is empty";
}
5.3 max_size()
cpp
cout << lst.max_size(); // 返回list可容纳的最大元素数
5.4 resize()
cpp
lst.resize(10); // 调整为10个元素,新增元素默认初始化
lst.resize(15, 5); // 调整为15个元素,新增元素初始化为5
6. 元素访问
6.1 front()
cpp
lst.front() = 5; // 修改第一个元素
int first = lst.front(); // 访问第一个元素
6.2 back()
cpp
lst.back() = 8; // 修改最后一个元素
int last = lst.back(); // 访问最后一个元素
7. 修改操作
7.1 push_back()
cpp
lst.push_back(10); // 在尾部插入10
7.2 push_front()
cpp
lst.push_front(5); // 在头部插入5
7.3 pop_back()
cpp
lst.pop_back(); // 删除尾部元素
7.4 pop_front()
cpp
lst.pop_front(); // 删除头部元素
7.5 insert()
cpp
auto it = lst.insert(lst.begin(), 15); // 在头部插入15
lst.insert(it, {1, 2, 3}); // 在指定位置插入多个元素
7.6 erase()
cpp
lst.erase(lst.begin()); // 删除第一个元素
lst.erase(lst.begin(), lst.end()); // 删除所有元素
7.7 clear()
cpp
lst.clear(); // 清空所有元素
7.8 swap()
cpp
list<int> lst2;
lst.swap(lst2); // 交换两个list的内容
8. 特殊操作
8.1 splice()
cpp
list<int> lst2 = {4, 5, 6};
lst.splice(lst.end(), lst2); // 将lst2所有元素移动到lst尾部
lst.splice(lst.begin(), lst2, lst2.begin()); // 移动lst2的第一个元素
8.2 remove()
cpp
lst.remove(5); // 删除所有值为5的元素
8.3 remove_if()
cpp
lst.remove_if([](int n){ return n%2 == 0; }); // 删除所有偶数
8.4 unique()
cpp
lst.unique(); // 删除连续重复元素
8.5 merge()
cpp
list<int> lst2 = {4, 5, 6};
lst.sort(); lst2.sort();
lst.merge(lst2); // 合并两个已排序list
8.6 sort()
cpp
lst.sort(); // 升序排序
lst.sort(greater<int>()); // 降序排序
8.7 reverse()
cpp
lst.reverse(); // 反转list
9. 迭代器
9.1 begin() & end()
cpp
for(auto it = lst.begin(); it != lst.end(); ++it) {
cout << *it << " ";
}
9.2 rbegin() & rend()
cpp
for(auto rit = lst.rbegin(); rit != lst.rend(); ++rit) {
cout << *rit << " "; // 反向遍历
}
10. 完整示例
cpp
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
int main() {
// 创建并初始化list
list<int> lst = {2, 3, 4};
// 头部和尾部操作
lst.push_front(1); // 头部插入1
lst.push_back(5); // 尾部插入5
// 访问元素
cout << "First element: " << lst.front() << endl;
cout << "Last element: " << lst.back() << endl;
// 插入元素
auto it = next(lst.begin(), 2); // 获取第3个位置的迭代器
lst.insert(it, {7, 8, 9}); // 在第3个位置插入7,8,9
// 删除元素
lst.pop_front(); // 删除头部元素
lst.remove(8); // 删除所有8
// 特殊操作
list<int> lst2 = {10, 11, 12};
lst.splice(lst.end(), lst2); // 合并lst2到lst
lst.sort(); // 排序
lst.unique(); // 去重
// 遍历list
cout << "All elements: ";
for(int num : lst) {
cout << num << " ";
}
cout << endl;
// 容量信息
cout << "Size: " << lst.size() << endl;
cout << "Is empty: " << (lst.empty() ? "Yes" : "No") << endl;
return 0;
}
11. 性能提示
- 在任何位置插入/删除元素性能都很好(O(1)O(1)O(1))
- 查找元素需要遍历(O(n)O(n)O(n))
- 迭代器在插入/删除操作后仍然有效(除非删除的是迭代器指向的元素)
- 适合频繁插入/删除但不需随机访问的场景