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) 不支持
相关推荐
Lucis__10 小时前
STL设计模式探秘:容器适配器&仿函数
c++·容器·stl·仿函数
百锦再10 小时前
第15章 并发编程
android·java·开发语言·python·rust·django·go
864记忆10 小时前
Qt QML 模块及其函数详解
开发语言·qt
无敌最俊朗@10 小时前
C++ 对象布局之padding(填充字节)
开发语言·c++
小龙报10 小时前
《DevC++支持C++11等与其软件分辨率低的解决办法》
c语言·c++·windows·蓝桥杯·pat考试·学习方法·dvc++
共享家952710 小时前
高级IO-poll
开发语言·操作系统·io
大佬,救命!!!11 小时前
C++函数式策略模式中配置修改
c++·学习笔记·迭代加深·企业级·函数式策略模式·多文件编译环境·json环境配置修改
Chiang木11 小时前
C++进阶:coroutine 协程
开发语言·c++·协程
蕓晨11 小时前
数据结构 图 的邻接表建立
数据结构·c++
ivy1598683771511 小时前
JM20329是一款高性能、低功耗的USB桥接芯片,实现串行接口(如SATA、IDE)与USB接口之间的数据转换。
c语言·开发语言·ide·嵌入式硬件·eureka·音视频·视频编解码