您的位置:首页 > 其它

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

2016-04-15 20:18 204 查看
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;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: