现在的位置: 首页 > 综合 > 正文

【STL】序列式容器细节

2018年04月23日 ⁄ 综合 ⁄ 共 2487字 ⁄ 字号 评论关闭

一、概论

1、序列式容器

array(build-in) C++内建

vector

heap 内含一个vector

priority-queue 内含一个heap

list

slist

deque

stack 内含一个deque

queue 内含一个deque

2、关联式容器

RB-tree

set 内含一个RB-tree

map 内含一个RB-tree

multiset 内含一个RB-tree

multimap 内含一个RB-tree

hashtable

hash_set 内含一个hashtable

hash_map 内含一个hashtable

hash_multiset 内含一个hashtable

hash_multimap 内含一个hashtable

3、所谓序列式容器,其中的元素都可序,但未必有序。

 

二、vector

1、vector的数据安排以及操作方式,与array非常相似,两者的唯一差别在于空间的运用的灵活性。

array是静态空间,一旦配置了就不能改变。

vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间以容纳新元素。

2、vector的实现技术,关键在于其对大小的控制以及重新配置时的数据移动效率。

3、vector提供random access iterator

4、vector的数据结构

线性连续空间

以两个迭代器start和finish分别指向配置得来的连续空间中目前已经被使用的范围,并以迭代器end_of_storage

指向整块连续空间(含备用空间)的尾端。

当增加新元素时,如果超过当时的容量,则容量会扩充至两倍。如果两倍容量仍不足,则扩充至足够大的容量。

容量大于等于其size。

容量的扩张必须经历“重新配置、元素移动、释放原空间”等过程,工程浩大。

5、vector的构造与内存管理

所谓动态增加大小,并不是在原空间之后接续新空间(因为无法保证原空间之后尚有可供配置的空间),而是以原大小的两倍

另外配置一块较大空间,然后将原内容拷贝过来,然后才开始在原内容之后构造新元素,并释放原空间。

因此,对vector的任何操作,一旦引起空间重新配置,指向原vector的所有迭代器就都失效了。

6、STL对于“插入操作”的标准规范:插入完成后,新节点将位于哨兵迭代器所指之节点的前方。

 

三、list

1、相较于vector的连续线性空间,list就显得复杂许多,它的好处是每次插入或删除一个元素,就配置或释放一个元素空间。

对于任何位置的元素插入或元素移除,list永远是常数时间。

2、list的实现是一个环状双向链表,只需要一个指针,便可以完整表现整个链表。

只要刻意在环状链表的尾端加上一个空白节点,便符合STL规范之“前闭后开”区间。

3、list提供 bidirectional iterator

 

四、deque

1、vector是单向开口的连续线性空间,而deque则是一种双向开口的连续线性空间。所谓双向开口,表示可以在头尾两端分别

做元素的插入和删除操作。

2、deque和vector的最大差异:

a、deque允许常数时间内对头端进行元素的插入或移除操作

b、deque没有容量概念,因为它是动态地以分段连续空间组合而成,随时可以增加一段新的空间并链接起来。

3、deque也提供random access iterator,但复杂度很高,除非必要,尽可能选择vector

4、deque的中控器

deque由一段一段的定量连续空间构成,deque采用一块所谓的map作为主控,这里的map是一小块连续空间,其中每

个元素都是指针,指向另一段连续线性空间,称为缓冲区。缓冲区才是deque的存储空间主体。

5、deque的迭代器

deque是分段连续空间,维持其“整体连续”假象的任务,落在了迭代器的operator++和operator--运算子身上。

每个缓冲区大小一样。

 

五、stack

1、stack是FILO的数据结构,只有一个出口。

2、stack以deque为底部结构,因此stack往往不被归类为container,而被归类为container adapter

3、stack不提供走访功能,也不提供迭代器。

 

六、queue

1、queue是FIFO的数据结构,有两个出口。

2、queue以deque为底部结构,因此queue往往不被归类为container,而被归类为container adapter

3、queue不提供遍历功能,也不提供迭代器。

 

七、heap

1、heap并不归属于STL容器组件,它是个幕后英雄,扮演priority queue 的助手。

2、priority queue允许用户以任何次序将任何元素推入容器内,但取出时一定是从优先级最高的元素开始取。

3、binary heap是一种完全二叉树,通过简单的位置规则,array可以轻易实现出完全二叉树,这种以array表述tree的方式,

我们称为隐式表述法。

4、array的缺点是无法动态改变大小,而heap却需要这项功能,因此,以vector代替array是更好的选择。

5、heap不提供遍历功能,也不提供迭代器。

6、经过排序后的heap不再是一个合法的heap,需要再做一个heap

 

八、priority queue

1、priority queue是一个拥有权值观念的queue,由于是queue,只允许在底端加入元素,并从顶端取出元素。

2、priority queue带有权值观念,其内的元素并非按照被推入的次序排列,而自动按元素的权值排列。

3、priority queue以vector为底部结构再加上heap处理规则,因此其往往不被归类为container,而被归类为container adapter

4、priority queue不提供遍历功能,也不提供迭代器。

 

九、slist

1、slist是单向链表,这个容器并不在标准规格之内。

2、slist的迭代器属于forward iterator,而list的迭代器输入bidirectional iterator

 

十、总结

序列式容器的重点在于vector、list、deque的理解,清楚了其内部实现,在实际中就可以应用得当。

 

抱歉!评论已关闭.