C++容器forward_list
定义
std::forward_list<T,Allocator>::forward_list - cppreference.cn - C++参考手册
- 单向链表 :每个元素(节点)包含数据和一个指向下一个 节点的指针。没有指向前一个节点的指针
- 非连续存储:元素在内存中分散存放,通过指针链接
- 高效修改 :在已知位置后插入或删除元素的时间复杂度为 O(1)
- 前向迭代 :只能从头到尾单向遍历,不支持反向迭代器(如
rbegin(), rend())
- 无
size() 成员函数 :为了最小化开销,forward_list 没有存储大小信息的成员,size() 操作需要遍历整个链表,时间复杂度为 O(n)
- 稳定迭代器 :与
list 类似,插入操作不会使其他元素的迭代器、指针或引用失效(被删除元素的迭代器除外
构造函数
1、默认构造函数
cpp
复制代码
int main()
{
system("chcp 65001");
forward_list<std::u8string> list1;
cout << "list1.empty()= " << boolalpha << list1.empty() << endl;
cout << "list1.max_size()= " << list1.max_size() << endl;
}
2、指定元素个数构造函数
cpp
复制代码
std::string getStringFromU8string(const std::u8string& u8str) {
return std::string(reinterpret_cast<const char*>(u8str.data()), u8str.size());
}
std::u8string getU8stingFromString(const std::string& str) {
return std::u8string(reinterpret_cast<const char8_t*>(str.data()), str.size());
}
int main()
{
system("chcp 65001");
forward_list<std::u8string> list1(3);
cout << "list1.empty()= " << boolalpha << list1.empty() << endl;
cout << "list1.max_size()= " << list1.max_size() << endl;
for (auto it : list1)
{
cout << "list1-> " << getStringFromU8string(it) << endl;
}
}
3、指定元素个数与默认值构造函数
cpp
复制代码
int main()
{
system("chcp 65001");
forward_list<std::u8string> list1(3, u8"&&");
cout << "list1.empty()= " << boolalpha << list1.empty() << endl;
cout << "list1.max_size()= " << list1.max_size() << endl;
for (auto it : list1)
{
cout << "list1-> " << getStringFromU8string(it) << endl;
}
}
4、拷贝构造函数
cpp
复制代码
int main()
{
system("chcp 65001");
forward_list<std::u8string> list1(3, u8"&&");
// 拷贝构造函数
forward_list<std::u8string> list2(list1);
cout << "list2.empty()= " << boolalpha << list2.empty() << endl;
cout << "list2.max_size()= " << list2.max_size() << endl;
for (auto it : list2)
{
cout << "list2-> " << getStringFromU8string(it) << endl;
}
}
5、移动构造函数
cpp
复制代码
int main()
{
system("chcp 65001");
forward_list<std::u8string> list1(3, u8"&&");
// 移动构造函数
forward_list<std::u8string> list2(std::move(list1));
cout << "list1.empty()= " << boolalpha << list1.empty() << endl;
cout << "list1.max_size()= " << list1.max_size() << endl;
cout << "list2.empty()= " << boolalpha << list2.empty() << endl;
cout << "list2.max_size()= " << list2.max_size() << endl;
for (auto it : list2)
{
cout << "list2-> " << getStringFromU8string(it) << endl;
}
}
6、范围构造函数
cpp
复制代码
int main()
{
system("chcp 65001");
std::array<std::u8string, 4> arr1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };
// 范围构造函数
forward_list<std::u8string> list1(arr1.rbegin(), arr1.rend());
cout << "list1.empty()= " << boolalpha << list1.empty() << endl;
cout << "list1.max_size()= " << list1.max_size() << endl;
for (auto it : list1)
{
cout << "list1-> " << getStringFromU8string(it) << endl;
}
}
7、指定列表构造函数
cpp
复制代码
int main()
{
system("chcp 65001");
// 指定列表构造函数
forward_list<std::u8string> list1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };
forward_list<std::u8string> list2{ u8"张三", u8"李四" };
cout << "list1.empty()= " << boolalpha << list1.empty() << endl;
cout << "list1.max_size()= " << list1.max_size() << endl;
for (auto it : list1)
{
cout << "list1-> " << getStringFromU8string(it) << endl;
}
}
元素访问
| 函数 |
描述 |
front() |
返回第一个元素的引用。 |
cpp
复制代码
int main()
{
system("chcp 65001");
forward_list<std::u8string> list1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };
cout << "list1.empty()= " << boolalpha << list1.empty() << endl;
cout << "list1.front()= " << (list1.empty() ? "" : getStringFromU8string(list1.front())) << endl;
}
迭代器
begin-end与cbegin-cend
cpp
复制代码
int main()
{
system("chcp 65001");
forward_list<std::u8string> list1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };
for (auto it : list1)
{
cout << "list1-> " << getStringFromU8string(it) << endl;
}
for (auto it = list1.begin(); it != list1.end(); it++)
{
cout << "begin-end, list1-> " << getStringFromU8string(*it) << endl;
}
for (auto it = list1.cbegin(); it != list1.cend(); it++)
{
cout << "cbegin-cend, list1-> " << getStringFromU8string(*it) << endl;
}
// 返回一个指向第一个元素之前的迭代器
list1.insert_after(list1.before_begin(), u8"测试");
for (auto it : list1)
{
cout << "insert_after-> " << getStringFromU8string(it) << endl;
}
}
容量大小
| 函数 |
描述 |
empty() |
如果 forward_list 为空,返回 true |
max_size() |
返回容器可容纳的最大元素数量 |
cpp
复制代码
int main()
{
system("chcp 65001");
forward_list<std::u8string> list1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };
cout << "list1.empty()= " << boolalpha << list1.empty() << endl;
cout << "list1.max_size()= " << list1.max_size() << endl;
}
修改操作
| 函数 |
描述 |
push_front(value) |
在开头插入一个元素 |
pop_front() |
删除第一个元素 |
emplace_front(args...) |
在开头就地构造一个元素(不用复制) |
emplace_after(pos, args...) |
在位置 pos 之后就地构造一个元素(不用复制) |
insert_after(pos, value) |
在位置 pos 之后插入一个元素 |
insert_after(pos, n, value) |
在位置 pos 之后 插入 n 个 value |
insert_after(pos, first, last) |
在位置 pos 之后 插入范围 [first, last) 的元素 |
erase_after(pos) |
删除位置 pos 之后的元素 |
erase_after(first, last) |
删除范围 (first, last) 的元素(即 first 之后到 last 之前) |
clear() |
删除所有元素。 |
resize(n) |
调整大小到 n。如果变大,新元素用默认值初始化 |
swap(other) |
与另一个 forward_list 交换内容 |
cpp
复制代码
int main()
{
system("chcp 65001");
forward_list<std::u8string> list1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };
// 头部添加元素
list1.push_front(u8"测试");
// 头部元素删除
list1.pop_front();
// 添加元素
list1.emplace_front(u8"测试");
list1.emplace_after(list1.before_begin(), u8"哈哈");
list1.insert_after(list1.before_begin(), u8"insert数据");
// 插入范围数据
std:array<std::u8string, 2> arr1 = { u8"张三",u8"李四" };
list1.insert_after(list1.begin(), arr1.begin(), arr1.end());
for (auto it : list1)
{
cout << "insert_after-> " << getStringFromU8string(it) << endl;
}
// 删除数据
list1.erase_after(list1.begin(), list1.end());
for (auto it : list1)
{
cout << "erase_after-> " << getStringFromU8string(it) << endl;
}
list1.clear();
}
单向链表操作
| 函数 |
描述 |
before_begin() |
返回一个指向第一个元素之前 的迭代器。这是 forward_list 的关键特性,用于在链表头部或任意位置后进行操作 |
splice_after(pos, other, it) |
将 other 中 it 指向的元素的下一个 元素移动到 fl 的 pos 之后 。O(1) |
splice_after(pos, other, first, last) |
将 other 中 (first, last) 范围的元素移动到 fl 的 pos 之后 。O(1) |
remove(value) |
删除所有值为 value 的元素 |
remove_if(pred) |
删除所有满足谓词 pred 的元素 |
unique() |
删除连续的重复元素(只保留一个) |
unique(pred) |
使用自定义比较函数删除连续的重复元素 |
sort() |
对元素进行排序(默认升序) |
sort(comp) |
使用自定义比较函数排序 |
reverse() |
反转 forward_list 中元素的顺序 |
merge(other) |
将已排序的 other 合并到 fl 中,并保持有序。other 变为空 |
cpp
复制代码
int main()
{
system("chcp 65001");
forward_list<std::u8string> list1 = { u8"北京", u8"上海", u8"广州", u8"深圳" };
// 添加元素
list1.emplace_front(u8"测试");
list1.emplace_after(list1.before_begin(), u8"哈哈");
// 移除数据
list1.remove(u8"哈哈");
list1.remove_if([](std::u8string it) {
return it == u8"测试";
});
for (auto it : list1)
{
cout << "list1-> " << getStringFromU8string(it) << endl;
}
// 排序
list1.sort();
for (auto it : list1)
{
cout << "sort-> " << getStringFromU8string(it) << endl;
}
// 转置
list1.reverse();
for (auto it : list1)
{
cout << "reverse-> " << getStringFromU8string(it) << endl;
}
}
其他
| 特性 |
std::forward_list |
std::list |
std::vector |
| 任意位置插入/删除 |
O(1) (已知位置后) |
O(1) (已知位置) |
O(n) |
| 头部插入/删除 |
O(1) |
O(1) |
O(n) |
| 尾部插入/删除 |
O(n) |
O(1) |
O(1) 均摊 |
| 随机访问 |
不支持 |
不支持 |
O(1) |
| 反向遍历 |
不支持 |
支持 |
支持 |
| 内存布局 |
非连续 (单向链表) |
非连续 (双向链表) |
连续 |
| 内存开销 |
最低 (每个节点一个指针) |
高 (每个节点两个指针) |
低 |
size() 复杂度 |
O(n) |
O(1) |
O(1) |
| 迭代器失效 |
仅被删除元素的迭代器失效 |
仅被删除元素的迭代器失效 |
插入/删除可能导致大量失效 |
splice 操作 |
O(1) |
O(1) |
不支持 |