《stl源码剖析》--序列式容器

来源:互联网 发布:c语言布尔类型头文件 编辑:程序博客网 时间:2024/05/17 23:21

stl中的序列式容器包括三个:vector,list和deque,对于每种容器,要清楚他内部使用的数据结构,还有相应的迭代器的定义。

vector容器

使用的数据结构

vector容器和数组非常相似,他和数组的区别是数组是静态空间,一旦定义,空间大小就不能改变,而vector在使用过程中空间可以动态增长,比数组更灵活。vector使用的数据结构是一段连续地址空间,还定义有三个成员变量,分别表示空间起始地址,存放下一个数据的地址和空间的结束地址,如下图所示:

当剩余空间为0时,向vector容器中插入数据会引发以下步骤:1,重新分配一块足够大的内存空间,2,把当前数据拷贝到该内存空间中,3,释放原内存空间。

迭代器的定义

由于vector使用的是连续地址空间,所以vector的迭代器可以直接定义为原生指针。

list容器

使用的数据结构

list内部使用的数据结构是双向链表,会使用两个数据结构:链表节点和链表本身。
链表节点就是一个普通的双向链表的节点,如下图所示:

prev指向前一个节点,data存储数据,next指向下一个节点。
链表本身的数据结构
由于list是个双向链表,所以只用存储一个链表节点,就可以遍历整个链表。
list链表存储一个头节点,如下图所示:


迭代器的定义

list迭代器不能使用原生指针,所以要自定义一个类型,并且重载该迭代器支持的操作符。
list迭代器不是一个随机存取迭代器,也就是说,它不支持+n,-n以及两个迭代器相减操作,
所以stl提供的很多算法,不能用在list迭代器上。
list迭代器的完整定义在130页,不难看懂。

deque容器

使用的数据结构

deque容器很有意思,他介于vector和list容器之间,deque使用的数据结构具体如下图所示:

deque中,只存储map数组。
map是个中控器,实际的数据存放在map元素指向的内存块中,内存块的大小是固定的。
map中控器有一点要注意,就是第一个指向内存块的元素并不一定是map的第一个元素,这样
可以保证deque在常数时间内在首部插入元素,这一点和list很相似。当map中指向内存块的元素是首元素
并且还要向deque首部插入元素时,需要重新为map分配一块更大的空间。同理,当向deque尾部插入元素时,也会
出现该情况。

迭代器的定义

deque的迭代器是个随机访问迭代器,和vector很类似,定义了+n以及两个迭代器相减操作,deque迭代器的结构如下图所示:

迭代器的cur指向当前元素,cur和last指向当前内存块存的使用范围,node指向
map中控器的当前元素。明白了数据结构,迭代器重载的各种操作实现起来也很简单。
0 0