stl里的容器按元素在容器内的排列方式,可以分为序列式和关联式两种。
所谓序列式容器,其中的元素时可序的,即元素集合呈线性关系。
C++本身提供了一个序列式容器array,stl提供了vector,list,deque,stack,queue,priority_queue等序列容器。其中stack和queue由于只是将deque盖头换面,在技术上称之为适配器。
1、Vector
vector的元素存储和访问方式和array很相似,唯一的不同就在于弹性。array是静态空间,一旦配置了就不能改变;vector是动态空间,随着元素的增多或减少,其配置空间的大小可以动态改变。
vector的迭代器:由于vector使用的是连续线性的空间,所以其迭代器实际就是原生指针,这显然是个Random Access Iterator。
空间配置策略:从效率考虑,当插入元素的时候,如果配置的空间不足,则扩充空间至当前的两倍,如果任然不足则扩充至所需空间。 插入或删除元素时,涉及元素的拷贝和初始化。
2、List
list是一个双向链表,每次插入或删除一个元素,就分配或释放一个元素的空间;所以list对空间的控制十分精确,而且任何位置的插入或删除需要的时间都是常数。list和vector是两种最常用的容器,什么时候选用哪种容器,视元素的多寡、元素的构造复杂度(是否有trivial copy ctor,assignment opt)以及元素存取的行为特性。
list的迭代器:list不能再以原生指针作为迭代器,而需要定义特定的iterator类。list迭代器是一种Bidirectional Iterator,支持单步的前进或后退操作。list迭代器有一个重要特点,就是插入操作不会造成原有迭代器的实效,这对vector是不成立的。
list的结构:list不仅是一个双向链表,而且是一个带头结点的环状双向链表。
list的sort方法:list不能使用stl提供的通用sort算法,因为sort算法只接受Random Access Iterator,所以提供了自己的sort方法。sort方法的实现在另一篇中有描述。
3、Deque
vector是单向开口的连续线性空间,deque则是一种双向开口的连续线性空间。所谓双向开口,意思是可以在头尾分别做元素的的安插和删除操作;vector当然也可以在头尾两端做动作,但是其头部动作效率奇差。deque和vector最大的差异在于:deque允许在常数时间内对两端进行元素的安插或移除操作;deque没有所谓容量的概念,因为它是以分段的连续空间组合而成,随时可以增加一段空间拼接起来,不存在像vector那样“因空间不足而分配一块更大的空间然后复制元素”问题。
deque的迭代器:deque提供random access iterator,但并不是原生指标。其实现的复杂度也很大,这也影响到相关算法的效率。所以如非必要,应该尽量使用vector而不是deque。对的确进行排序时,可以先将元素复制到一个vector,排序后再复制回deque。
deque的存储结构:deque采用的是一种分段连续空间存储结构,采用一个map(不是stl中的map)来管理这些空间段。每个空间段的大小是固定的,当有新元素加入而空间不足时,就分配一个新的空间段。当空间段的个数增加时,可能需要分配一个更大的map。 deque的这种结构,是的其迭代器上的操作可能需要跨越空间段,因而具有相当的复杂度。
4、Stack
stack是一种先进后出的数据结构,只可以在顶端进行元素操作。如果有某种双向开口的数据结构,将其接口改变,符合“先进后出”的特性,就可以形成一个stack:deque和list都是这样的结构。
因此stack的实现非常简单,它以某种现有的容器作为存储的实现,定义新的接口。这种容器被称为container adapter。
template <class T, class Sequence=Deque<T> >
class stack
{
...
}
如上所示,stack默认使用deque来实现,你也可以使用list: stack<int, list<int> >;
stack不支持对元素的遍历,因此没有迭代器。
5、Queue
queue是一宗先进先出的数据结构,它的实现方案和stack基本一样。也是属于container adapter一类。可以基于deque和list。
queue没有迭代器。
6、heap
heap并不是stl中的一种容器,它实际是以vector作为完全二叉树的存储结构,再加上一些heap算法。它是priority_queue的背后英雄。
stl定义了一些heap操作的算法:包括建堆,push_heap,pop_heap,sort_heap等,基本上和《算法导论》堆排序一章介绍的一致。
7、Priority Queue
priority queue是一种拥有权值概念的queue,加入的元素按权值大小排列。priority_queue也是container adapter,它以vector为存储结构,再以heap算法进行处理:priority_queue的元素存放在一个vector当中,按元素权值排列成一个heap。
priority queue同样没有迭代器。