STL学习笔记——序列式容器

来源:互联网 发布:丽水学院网络怎么样 编辑:程序博客网 时间:2024/05/20 23:05

vector 维护的是一个连续线性空间,这点和array类似,但vector更灵活,支持空间的扩展。如果当前分配的线性空间已满,又要加入新的元素,就要能扩展空间,就要选择好策略。STL的策略是重新找一块原容量2倍的存储块,然后将原来空间里的所有元素复制过来,再填入新元素。(因为连续存储,不能再原存储块后扩展)

至于为什么是2倍而不是其他的策略,这值得思考:

为什么不是每次需要扩充时:1.新容量=原容量+N(N为1,2,3,4.......),2.新容量=原容量*1.5,或者新容量=原容量*3;

假设添加m元素到空的vector中:

方案一:新容量=原容量+N 是常数扩充,需要(m-1)/N+1次扩充,每次复制k*N个元素(k=1,2,3,4......),时间复杂度为O(m^2)  ;

方案二:新容量=原容量*N 是倍数扩充,需要logN(m-1)次扩充,每次复制k*N个元素(k=1,2,3,4......),时间复杂度为O(m*logm)  。

可见方案二在时间上比较节省,但空间上会比较浪费,最坏的情况下,可能会有接近一半(k=2的情况下)的空间被申请但没存任何数据。

STL设计者站在时间优先的角度,又不原造成过多的空间浪费,选择了两倍扩容的策略。而java采用1.5倍扩容。


list维护的是一个链表,更准确说是双向链表,更准确说是环状双向链表。list的last 迭代器指向的节点数据为空,但next指针指向first迭代器指向的节点。

所以用一个指针link_type node(指向那个空节点)就可以表示整个环状双向链表。

iterator end()  {return node;}

iterator begin()   {return (link_type)((*node).next);}

bool empty()  {return node->next==node;}



0 0
原创粉丝点击