C++ 头文件系列(forward_list)
2017-01-22 10:55
267 查看
简介
forwrad_list字面意思为前向列表,但实际上它是一种单向列表,只能从单一方向遍历。单向链表实现
forward_list内部是用单向列表实现的,并且设计该库的时候就是以近乎手写的单向链表的运行效率(时间上和空间上)为目的的。 这导致了它是唯一一个C++标准库容器中没有size成员函数的容器, 因为维护这样一个信息会造成效率上的轻微损失。作为单向链表,它有以下几个属性:
潜在可能的非连续内存分配
线性时间的元素位置获取
常数时间的元素插入、删除、移动
与list的共性
因为它们的内部实现都是通过链表(不管是单链表还是双链表),所以forwrd_list类模版具有一些与list相同的特殊函数:splice_after
remove、remove_if
unique
merge
sort
reverse
与list的差异
明显的,forward_list是单向链表,内部只维护了单向遍历的信息。 因此,forward_list的迭代器是前向迭代器(forward intertor)。除此之外,它们的插入操作也有明显的不同,具体体现在传入的迭代器上:
list::insert:在传入的迭代器之前插入。
forward_list::insert:在传入的迭代器之后插入。
我们来看,为什么标准库要放弃接口语义的一致性,采用不一样的接口设计。
节点修改策略
单向 VS 双向
典型的链表分单向和双向,基本上每一个方向上都需要额外的空间来保存顺序信息(即前一个和后一个元素)。 双向链表保存有两个方向的链接, 而单向链表只有一个方向。节点修改
当涉及到链表节点的修改时,例如插入、移动等,问题就变得明显了:对于链表来说,修改单个节点实际上涉及到3个节点的信息----当前节点、前驱节点lis、后继节点(修改前后节点的前后节点的链接信息是必要的)。但是,可以更简单点:双向链表的前驱和后继信息可以间接地通过当前节点得到,因为当前节点有足够的信息 。也就是说,在修改节点时,我只要传入该节点就可以了;而单向链表单个节点可以通过链接信息获得后继节点。
传入前驱节点迭代器
实际上,forward_list库做得更好,它的相关接口只需要我们传入一个节点迭代器。 这些接口包括(分别对应常见的非after版本):insert_after
emplace_after
erase_after
那么这怎么做到的呢? forward_list的策略是----传入前驱节点的迭代器。 这样一来,所有需要的节点信息都能够直接间接地得到。 Great!
但是这也有一个问题:怎么在头部插入一个元素呢?毕竟头节点没有前驱节点。 哈哈,这就是为什么这个类模版提供了两个非常奇怪的函数, 它们是专门为上述三个函数提供服务的(-_-):
before_begin
before_cbegin
所以现在你也知道了,为什么随笔开头的示意图有一个灰色的节点了吧。ヽ(^o^)ノ
相关文章推荐
- C++ 头文件系列(list)
- linux 内核链表操作头文件list.h C++
- C++容器之forward_list
- C++ 头文件系列(deque)
- C++ 头文件系列(map)
- C++ 头文件系列(vector)
- Silverlight实用窍门系列:22.Silverlight使用WebService调用C++,Delphi编写的DLL文件【实例源码下载】
- C++ 头文件系列(vector)_0
- C++ 头文件系列(array)
- C++编程入门系列之二十四(C++程序设计必知:多文件结构和编译预处理命令)
- C++ 头文件系列(unordered_map、unordered_set)
- PE文件学习系列笔记四-C++实现PE文件的分析
- C++ list容器系列功能函数详解
- linux下C++开发系列(六)——文件IO相关的系统调用
- C++ 头文件系列(array)
- 【C++ STL应用与实现】7: 如何使用std::forward_list 单链表 (since C++11)
- Silverlight实用窍门系列:22.Silverlight使用WebService调用C++,Delphi编写的DLL文件【实例源码下载】
- 鸡啄米:C++编程入门系列之二十四(C++程序设计必知:多文件结构和编译预处理命令)
- C++ 将文件夹中文件写入list.txt文件中
- C++ 头文件系列(stack)