1 std::forward_list 的概述
1.1 什么是 std::forward_list?
std::forward_list 是 C++ 标准模板库(STL)中的一个容器,它表示一个单向链表。相比于 std::list,std::forward_list 在存储和操作上更加简洁,从而减小了空间开销。单向链表意味着它只支持从前往后的遍历,即只有前向迭代器,而不支持从后往前的遍历。
std::forward_list 的基本特性如下:
- 单向性:forward_list 中的迭代器只支持向前移动,不支持向后移动,因此不能从尾部向前遍历链表。
- 插入和删除操作:由于forward_list 是链表结构,因此在链表头部插入和删除元素的时间复杂度是常数。但需要注意的是,由于它只支持前向迭代,所以插入和删除操作在链表的其他位置可能会相对复杂一些。
- 空间效率:相比于 std::list(双向链表),std::forward_list 节省了用于存储指向下一个和上一个节点的指针的空间,因此其空间开销较小。
使用 std::forward_list 时,需要包含头文件<forward_list>。下面是一个简单的使用示例:
#include <iostream>
#include <forward_list>
int main()
{
// 创建一个空的forward_list
std::forward_list<int> flst;
// 向forward_list的头部插入元素
flst.push_front(1);
flst.push_front(2);
flst.push_front(3);
// 移除forward_list的一个元素
flst.pop_front();
// 遍历forward_list并打印元素
for (auto it = flst.begin(); it != flst.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
return 0;
}
上面代码的输出为:
2 1
在访问 forward_list 的第一个元素时,也可以使用 before_begin() 方法,这个方法返回的是第一个元素的前一个元素(也就是一个虚设的元素),不能直接解引用。但是,可以通过加 1 操作( std::advance(it, 1) )来访问第一个元素。
总体而言,std::forward_list 是一个单向链表容器,适用于那些只需要单向遍历数据结构的场景,它可以有效地节省空间,并提供常数时间的头部插入和删除操作。
1.2 std::forward_list 的使用场景
以下是std::forward_list的主要使用场景:
(1)内存空间有限: 当内存使用非常紧张,且每个字节都显得宝贵时,std::forward_list 是一个很好的选择。由于它只存储单个指针,相比双向链表(如 std::list)或动态数组(如 std::vector),它占用的空间更少。因此,在需要节省内存的场景中,std::forward_list 是理想的容器。
(2)频繁在头部插入或删除元素: 如果你的应用场景需要频繁在列表的头部插入或删除元素,std::forward_list 是一个很好的选择。由于单向链表的结构特性,它在头部插入或删除元素的时间复杂度几乎是常数时间,不依赖于容器的大小。因此,对于需要频繁进行此类操作的场景,std::forward_list 比其他类型的容器更加高效。
(3)不需要双向遍历: 如果应用场景不需要双向遍历元素,那么 std::forward_list 比 std::list 更加高效。单向链表只支持从前往后的遍历,这意味着它不需要存储额外的指针来实现双向遍历,从而节省了空间。在只需要单向遍历的场景中,使用 std::forward_list 可以避免不必要的空间开销。
2 声明与初始化
2.1 声明
首先,需要包含 <forward_list> 头文件,然后声明一个 std::forward_list 变量,并指定类型。
#include <forward_list>
std::forward_list<Type> listName;
其中 Type 是元素的类型,listName 是 unordered_set 变量的名称。
2.2 初始化
std::forward_list 可以通过多种方式初始化。以下是一些常见的初始化方法:
(1)默认初始化
创建一个空的 forward_list:
std::forward_list<int> emptyList;
(2)使用列表初始化
使用花括号 {} 初始化 forward_list,其中可以包含多个元素:
std::forward_list<int> list = {
1, 2, 3, 4, 5};
(3)使用迭代器范围初始化
如果有一个已存在的容器或数组,并希望使用它的元素来初始化 forward_list,可以使用迭代器范围:
std::vector<int> vec = {
1, 2, 3, 4, 5};
std::forward_list<int> list(vec.begin(), vec.end());
(4)使用 assign 方法初始化
可以先创建一个空的 forward_list,然后使用 assign 方法分配一组值给它:
std::forward_list<int> list;
list.assign({
10