STL::forward_list之前向链表

本文详细介绍了C++标准库中的forward_list容器。它是一种高效的单向链表实现,支持快速插入和删除操作。文章还探讨了forward_list与list的区别、内部实现原理以及应用场景。

本文是Devour Heavens撰写整理的关于C++标准库的知识,所有资料均来自于C++官方文档,欢迎转载。但是为了尊重原作者的劳动,请注明出处!谢谢!

class template

forward_list

<forward_list>
template < class T, class Alloc = allocator<T> > class forward_list;

Forward list

前向链表是序列容器,使固定时间插入和擦除操作序列内的任何地方。

前向链表的实现方式和单链表相同;单链表可以存储所包含的每个元素在不同的和无关的存储位置。

在序列中顺序保存每个元素指向下一个元素的关联。

forward_list容器与list容器的主要设计区别是list保持内部唯一的一个链接到下一个元素,而后者则保持每个元素的两个链接:一个指向下一个元素和一个前一个。允许高效在两个方向迭代,但每个元素的消耗额外的存储空间,并轻微较高的时间开销插入和删除元素的迭代。forward_list对象,从而比list对象更有效率,虽然他们只能向前遍历。

与其他的基本标准序列容器(array,vector和deque)相比,forward_list一般在容器内的任何位置中的元素的插入、提取和移动操作效率更高,因此在算法中较密集的使用这些操作,例如排序算法。

相比其他序列容器,forward_lists的主要缺点是缺乏直接访问他们的位置的元素,例如,要进入第六个元素在forward_list的一个遍历从一开始就到那个位置,这需要线性时间之间的距离。他们也消耗了一些额外的内存保持连接信息相关联的每个元素(这可能是一个小型的元素的大链表的重要因素)。

考虑到forward_list类模板设计的性能:根据设计,它是作为一个简单的手写C风格的单链表一样高效,实际上是仅有的一个标准容器故意缺乏其大小的成员函数是出于效率的考虑。由于其作为一个链表的性质,有一个大小成员在固定的时间,需要保持一个内部的计数器保存其大小(和链表一样)。这会消耗一些额外的存储和使插入和删除操作,效率较低。为了获得一个forward_list对象的大小,可以用其开始和结束,这是一个线性时间的操作距离算法。

容器属性

序列

    在一个严格的线性序列中序列容器的元素是有序的。个别元素的访问是通过他们在这个序列中的位置。

链表

   每个元素保持如何找到下一个元素的信息,允许常量时间在特定元素(甚至整个范围)后进行插入和擦除操作,但没有直接随机存取。  

分配器的获取

   容器使用一个分配器对象动态地处理其存储需求。

模板参数

T

   元素的类型。
    作为成员类型forward_list:: value_type的别名。

Alloc

   用来定义存储分配模型的分配器对象的类型。默认情况下使用了分配器类模板,它定义了最简单的内存分配模式和单独存在。
   

   别名成员类型forward_list的::allocator_type的。

 

在参考的forward_list成员函数,这些相同的名称被假定为模板参数。

成员类型   

成员类型定义备注
value_typeThe first template parameter (T) 
allocator_typeThe second template parameter (Alloc)defaults to: allocator<value_type>
referencevalue_type& 
const_referenceconst value_type& 
pointerallocator_traits<allocator_type>::pointerfor the default allocator: value_type*
const_pointerallocator_traits<allocator_type>::const_pointerfor the default allocator: const value_type*
iteratora forward iterator to value_typeconvertible to const_iterator
const_iteratora forward iterator to const value_type 
size_typean unsigned integral typeusually the same as size_t
difference_typea signed integral typeusually the same as ptrdiff_t

 成员函数

迭代器

容量

元素的获取

修饰符

操作

观察者

全局函数

 

### C++ std::forward_list 使用指南和常见问题 #### 1. 简介 `std::forward_list` 是 C++ 标准模板库(STL)中的一种单向链表容器,它只支持从头部插入元素,并且不提供随机访问功能。与 `std::list` 不同,`std::forward_list` 只维护一个指向下一个节点的指针,因此它的内存开销较小[^2]。 #### 2. 基本特性 - **单向链表**:`std::forward_list` 的每个节点仅包含一个指向下一个节点的指针,这使得它在某些场景下比 `std::list` 更节省内存。 - **无尾指针**:`std::forward_list` 不维护尾指针,因此无法在常数时间内访问最后一个元素。 - **高效头部插入**:在头部插入元素的操作非常高效,时间复杂度为 O(1)。 #### 3. 构造函数 `std::forward_list` 提供了多种构造方式,包括默认构造、指定大小构造、使用初始化列表构造以及通过迭代器范围构造等[^4]。 ```cpp #include <iostream> #include <forward_list> int main() { // 创建一个空的 forward_list std::forward_list<int> fl1; // 使用初始化列表构造 forward_list std::forward_list<int> fl2{1, 2, 3, 4, 5}; // 通过迭代器范围构造 forward_list std::forward_list<int> fl3(fl2.begin(), fl2.end()); return 0; } ``` #### 4. 操作函数 `std::forward_list` 提供了一系列操作函数来管理其元素,包括插入、删除、遍历等。 - **插入操作**: - `push_front`:在头部插入一个元素。 - `emplace_front`:在头部构造一个元素。 - `insert_after`:在指定位置之后插入一个或多个元素。 - **删除操作**: - `pop_front`:删除头部元素。 - `erase_after`:删除指定位置之后的一个或多个元素。 - **其他操作**: - `before_begin`:返回一个特殊的迭代器,用于表示第一个元素之前的虚拟位置。 - `empty`:检查列表是否为空。 - `merge`:将两个已排序的 `std::forward_list` 合并为一个。 ```cpp #include <iostream> #include <forward_list> int main() { std::forward_list<int> fl = {3, 1, 4, 1, 5}; // 在头部插入元素 fl.push_front(9); // 删除头部元素 fl.pop_front(); // 插入元素到指定位置之后 auto it = fl.begin(); ++it; // 移动到第二个元素之后 fl.insert_after(it, 2); // 遍历并输出元素 for (const auto& elem : fl) { std::cout << elem << " "; } std::cout << std::endl; return 0; } ``` #### 5. 常见问题 ##### Q: 如何遍历 `std::forward_list`? A: 由于 `std::forward_list` 不支持随机访问,只能通过迭代器从前向后遍历[^4]。 ```cpp for (auto it = fl.begin(); it != fl.end(); ++it) { std::cout << *it << " "; } ``` ##### Q: `std::forward_list` 是否支持尾部插入? A: 不支持直接的尾部插入操作。如果需要在尾部插入元素,可以通过 `insert_after` 和 `before_begin` 结合使用来实现。 ```cpp fl.insert_after(std::prev(fl.end()), 6); ``` ##### Q: `std::forward_list` 和 `std::list` 的主要区别是什么? A: `std::forward_list` 是单向链表,而 `std::list` 是双向链表。`std::forward_list` 不维护尾指针,因此更节省内存,但无法在常数时间内访问最后一个元素[^1]。 ####
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值