C++容器forward_list

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-endcbegin-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) otherit 指向的元素的下一个 元素移动到 flpos 之后O(1)
splice_after(pos, other, first, last) other(first, last) 范围的元素移动到 flpos 之后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) 不支持
相关推荐
小灰灰搞电子5 分钟前
Rust suppaftp 库详解:基于 FTP 客户端实战指南
开发语言·后端·rust
编码浪子7 分钟前
Rust unsafe 与 FFI 互操作生产级实战:把危险关进笼子的四道闸门
开发语言·后端·rust
估值探索者21 分钟前
【AI+量化实战 #05】财报季的信息洪流:用LLM给业绩预告分类+算事件窗口收益
java·c语言·c++·人工智能·python·分类·数据挖掘
Zixhy2 小时前
手撕Reactor模型实现同步高并发服务器及Muduo网络库深入解析
linux·服务器·网络·数据库·c++
傻啦嘿哟8 小时前
某招聘平台爬虫:爬取招聘岗位数据,分析各城市薪资水平
开发语言·爬虫·python
2501_933670798 小时前
2026秋招量化分析岗技能栈:Python、SQL、统计建模、回测项目怎么准备
开发语言·python·sql
李少兄9 小时前
JavaScript 数据类型完全指南
开发语言·javascript·ecmascript
码匠许师傅9 小时前
【设计模式精讲】29.行为型模式总结与对比(Behavioral Patterns Summary)
c++·设计模式·uml
Seoyoneh10 小时前
Agentic Workflow编排架构:云客服从“被动响应”迈向“主动执行”的技术实现
java·开发语言·架构
啦啦啦啦啦zzzz10 小时前
Logger的组装(c++20)
c++·算法·c++20