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-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) 不支持
相关推荐
Aurorar0rua2 小时前
CS50 x 2024 Notes Python - 02
开发语言·python·学习方法
zyseo82 小时前
谷歌SEO 网站迁移 301 映射脚本:旧站 URL 自动匹配新站结构
开发语言·python
cu1432 小时前
细谈IT65631的具体功能与其应用
c++·单片机·嵌入式硬件
清水白石0082 小时前
React Native与Flutter长期维护成本对比
开发语言·数据库
幻智星科技2 小时前
Karatsuba与CSD优化FPGA大数乘法
c++·fpga开发·密码学
麦序子2 小时前
用 Python + python-docx 批量生成带表格样式的装修报价单 Word 文档(含合计公式)
开发语言·python·自然语言处理·word·python3.11
1-1=02 小时前
Python PyCharm
开发语言·python·pycharm
牛肉胡辣汤2 小时前
Blender + Three.js 开发讲解:从 .blend 到能转的产品页
开发语言·javascript·blender
惊讶的猫2 小时前
Spring AOP
java·开发语言
flower9803232 小时前
C++消息总线软件开发框架AI重构版
c++·设计模式·架构