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) 不支持
相关推荐
ceclar1233 小时前
C++容器list
java·c++·list
夏玉林的学习之路3 小时前
Anaconda的常用指令
开发语言·windows·python
大肘子咒你3 小时前
数字狂潮来袭
数据结构·c++·1024程序员节
hansang_IR3 小时前
【算法速成课 3】康托展开(Cantor Expansion)/ 题解 P3014 [USACO11FEB] Cow Line S
c++·算法·状态压缩·康托展开·排列映射
m0_748233643 小时前
【类与对象(中)】C++类默认成员函数全解析
开发语言·c++·算法
郝学胜-神的一滴3 小时前
使用 Python 元类与属性实现惰性加载:Effective Python 第47条
linux·服务器·开发语言·python
散峰而望4 小时前
基本魔法语言分支和循环 (二) (C语言)
c语言·开发语言·github·visual studio
前端世界4 小时前
用Python手写一个能识花的感知器模型——Iris分类实战详解
开发语言·python·分类
心.c5 小时前
深拷贝浅拷贝
开发语言·前端·javascript·ecmascript