更多 C++语法知识在 C++语言学记专栏
往期 STL 容器看点:
这篇文章是关于 C++所有数据结构概览中的单独专题
顺序容器 vector array list deque forward_list 关联容器 set&multiset map&multimap 无序关联容器 Unordered set&multiset Unordered map&multimap 容器适配器 stack queue priority_queue 其他容器 string
首先,请确保包含了头文件:
#include <list>
std::list 是一个双向链表,它的主要优点是在序列的任何位置进行插入和删除操作都非常快(O(1)),但代价是失去了快速随机访问的能力。
1. 构造函数 (Constructors)
用于创建和初始化一个 list。
-
list()-
功能:默认构造函数,创建一个空的
list。 -
示例:
std::list<int> l1;
-
-
list(size_type count, const T& value)-
功能:创建包含
count个元素的list,每个元素都被初始化为value。 -
示例:
std::list<int> l2(5, 10); // 创建包含 5 个 int 的 list,每个都是 10
-
-
list(size_type count)(C++11 起)-
功能:创建包含
count个元素的list,并对每个元素进行值初始化。 -
示例:
std::list<int> l3(5); // 创建包含 5 个 int 的 list,每个都是 0
-
-
list(InputIt first, InputIt last)-
功能:使用迭代器范围
[first, last)内的元素来构造list。 -
示例:
int arr[] = {1, 2, 3, 4, 5}; std::list<int> l4(arr, arr + 5);
-
-
list(const list& other)-
功能:拷贝构造函数,创建一个与
other内容相同的list。 -
示例:
std::list<int> l5(l4);
-
-
list(list&& other)(C++11)-
功能:移动构造函数,接管
other的资源。 -
示例:
std::list<int> l6(std::move(l5));
-
-
list(std::initializer_list<T> init)(C++11)-
功能:使用初始化列表来构造
list。 -
示例:
std::list<int> l7 = {1, 2, 3, 4, 5};
-
2. 迭代器 (Iterators)
用于遍历 list 中的元素。
-
begin() / cbegin()- 功能:返回指向
list第一个元素的迭代器。
- 功能:返回指向
-
end() / cend()- 功能:返回指向
list尾端(最后一个元素的下一个位置)的迭代器。
- 功能:返回指向
-
rbegin() / crbegin()- 功能:返回指向
list最后一个元素的反向迭代器。
- 功能:返回指向
-
rend() / crend()- 功能:返回指向
list第一个元素之前位置的反向迭代器。
- 功能:返回指向
重要提示:list 的迭代器是双向迭代器 (Bidirectional Iterator),不是随机访问迭代器。这意味着你只能对它进行 ++ 和 -- 操作,不能进行 it + 5 或 it > it2 这样的操作。
示例:
std::list<int> l = {10, 20, 30};
// 正向遍历
for(auto it = l.begin(); it != l.end(); ++it) {
std::cout << *it << " "; // 输出: 10 20 30
}
// 反向遍历
for(auto it = l.rbegin(); it != l.rend(); ++it) {
std::cout << *it << " "; // 输出: 30 20 10
}
3. 大小 (Size)
管理 list 的大小。
-
size()- 功能:返回
list中实际元素的数量。
- 功能:返回
-
empty()- 功能:检查
list是否为空(即size() == 0)。
- 功能:检查
-
max_size()- 功能:返回
list理论上能容纳的最大元素数量。
- 功能:返回
重要提示:list 没有 capacity() 和 reserve() 方法。因为链表是基于节点的非连续存储,每个节点都是独立分配内存的,所以不存在预留空间的概念。
4. 元素访问 (Element Access)
获取 list 中的首尾元素。
-
front()- 功能:返回对第一个元素的引用。
-
back()- 功能:返回对最后一个元素的引用。
重要提示:list 没有 operator[] 或 .at() 方法。因为它的非连续内存结构,无法在 O(1) 时间内进行随机访问。要访问中间元素,必须从头或尾开始遍历。
示例:
std::list<int> l = {10, 20, 30, 40};
int first = l.front(); // first = 10
int last = l.back(); // last = 40
5. 修改器 (Modifiers)
改变 list 的内容,这是 list 的核心优势所在。
-
assign(): 功能同vector。 -
push_back(const T& value)/emplace_back(...)- 功能:在
list的末尾添加一个元素。保证为 O(1)。
- 功能:在
-
pop_back()- 功能:移除
list的最后一个元素。O(1)。
- 功能:移除
-
push_front(const T& value)/emplace_front(...)- 功能:在
list的头部添加一个元素。这是list的一个巨大优势。O(1)。
- 功能:在
-
pop_front()- 功能:移除
list的第一个元素。O(1)。
- 功能:移除
-
insert(const_iterator pos, ...)- 功能:在迭代器
pos指向的位置之前插入元素。只要有迭代器,这个操作就是 O(1),远快于vector的 O(n)。
- 功能:在迭代器
-
erase(const_iterator pos)/erase(const_iterator first, const_iterator last)- 功能:移除指定位置或范围的元素。同样,只要有迭代器,单个元素的删除就是 O(1)。
-
swap(list& other): 功能同vector,O(1)。 -
clear(): 功能同vector。 -
resize(): 功能同vector。
示例:
std::list<int> l = {10, 20, 30};
l.push_front(5); // l: {5, 10, 20, 30}
l.push_back(35); // l: {5, 10, 20, 30, 35}
auto it = l.begin();
std::advance(it, 2); // 移动迭代器到 20 的位置
l.insert(it, 15); // 在 20 前插入 15, O(1) 操作。l: {5, 10, 15, 20, 30, 35}
6. 特有的链表操作 (Specific List Operations)
这些是 list 独有的、非常高效的操作。
-
splice(const_iterator pos, list& other, ...)- 功能:拼接。将
other链表中的一个或多个节点移动到当前list的pos位置。这个过程只移动指针,不涉及元素的拷贝或移动,因此是极快的 O(1) 操作(移动整个链表)或 O(n)(移动other中N个元素)。
- 功能:拼接。将
-
merge(list& other)- 功能:合并。将已排序的
other链表合并到当前已排序的list中,结果仍然保持有序。other在此操作后会变为空。O(n)。
- 功能:合并。将已排序的
-
sort()- 功能:对链表进行内部排序。不能使用
std::sort(l.begin(), l.end()),因为它需要随机访问迭代器。
- 功能:对链表进行内部排序。不能使用
-
unique()- 功能:移除连续的重复元素。
-
reverse()- 功能:反转链表中元素的顺序。O(n)。
-
remove(const T& value)- 功能:移除所有等于
value的元素。
- 功能:移除所有等于
-
remove_if(UnaryPredicate p)- 功能:移除所有使谓词
p返回true的元素。
- 功能:移除所有使谓词
示例:
std::list<int> l1 = {1, 10, 20};
std::list<int> l2 = {5, 15};
// splice 示例
auto it = l1.begin();
it++; // 指向 10
l1.splice(it, l2); // 将 l2 的所有元素移动到 l1 的 10 之前
// l1: {1, 5, 15, 10, 20}, l2: {}
// sort 和 merge 示例
std::list<int> listA = {10, 30, 5};
std::list<int> listB = {20, 4, 40};
listA.sort(); // listA: {5, 10, 30}
listB.sort(); // listB: {4, 20, 40}
listA.merge(listB); // listA: {4, 5, 10, 20, 30, 40}, listB: {}
// unique 示例
std::list<int> l3 = {1, 2, 2, 3, 3, 3, 4};
l3.unique(); // l3: {1, 2, 3, 4}
7. 非成员函数 (Non-member functions)
-
比较运算符 (
==,!=,<,>,<=,>=)- 功能:以字典序比较两个
list的内容。
- 功能:以字典序比较两个
-
std::swap(list& a, list& b)- 功能:与成员函数
swap等效。
- 功能:与成员函数
-
std::erase(list<T>& c, const U& value)(C++20)- 功能:移除
c中所有等于value的元素。等效于成员函数remove。
- 功能:移除
-
std::erase_if(list<T>& c, UnaryPredicate p)(C++20)- 功能:移除
c中所有使一元谓词p返回true的元素。等效于成员函数remove_if。
- 功能:移除
下一个更新预告 std::deque
873

被折叠的 条评论
为什么被折叠?



