《stl源码剖析》剖析

这段时间,重读了侯捷先生的《stl源码剖析》,感受跟第一次读还是有不一样的。有些以前比较难以理解的点,现在能轻松看懂。两次读下来,感觉自己对stl整体模块开始有了粗浅的认识。下面请允许我说下对stl粗浅的几点认识,只讲重点:

1 空间分配器(allocator):

sgi stl(以下说stl都是指sgi版本)采用两级分配策略,1)大块内存申请时分配,不用时即刻销毁,不回收利用;2)小块内存销毁时回收利用,如果确实没有就重新分配,分配时也是大块分配(chunk allocation)。大和小的区别是128byte。

2 容器(container):

分序列容器和关联容器,区分标准是:是否以key作索引去找值。

序列容器:

1)vector

最常见,可以看做是可以自动管理增删操作的array,重点要记住 A 内存不足时分配策略是double, B index 操作O(1),增删O(n)

2)list

双向链表,即每个节点同时有next和prev指针, 两两节点的内存地址很可能不是连续的,故 index操作O(n),增删O(1)

3)deque

做为队列(queue)和stack的幕后功臣,与vector一样,可以在尾端增删,但与vector不同,它还是从头端增删。因此从功能集合上说,vector只是它的子集。那为什么deque不取代vector呢?答案是复杂性,这也很自然,要实现更多功能,复杂度自然也要增加的。deque像是vector和list的结合版,如果把list的每个节点做成是一个vector,基本上就是deque了。调度是用一个中控器,它相当于一个代理,客户端把命令发给它,然后它调度底层数据来实现功能呢。

4)priority queue

用完全二叉树构造的堆来实现,但由于完全二叉树每个节点的父子关系都完全符合数学公式,因此底层改用vector做数据结构。

关联容器:

关联容器就是能用key来找到value,因此查找是关联容器的天然使命。高效率的查找有二叉查找树(logN),hash(理想情况O(1),但内存较大(可能有多余未被使用的内存)),等等。

1) 二叉查找树:

某些情况下,树可能会不平衡,某个节点的子树高度差很多,从而影响查找效率。因此最好是平衡(或较平衡)的二叉树。avl树和红黑树都是平衡二叉树。stl一般都选红黑树,原因我也不清楚。





你可能感兴趣的:(STL)