您的位置:首页 > 其它

STL源码剖析(四)序列式容器(vector,list)

2017-04-06 17:43 417 查看
容器分为:

序列式容器:array,vector(用算法呈现heap(由heap实现priority-queue)),list,deque(配接器(stack,queue))

关联式容器:RB-tree(set,map,multiset,multimap),hashtable(hash_set,hash_map,hash_multiset,hash_multimap)

内含关系:heap内含一个vector,stack和queue内含一个deque,set/map/multiset/multimap内含RB_tree。

vector:

数据安排和操作方式,与array相似,唯一差别在于空间运用的灵活性。

array是静态空间,一旦配置了就不能改变(若空间不足:1.申请空间,2.copy,3.free之前空间)

vector是动态空间

vector迭代器:

vector维护的是一个连续线性空间,不管元素型别,普通指针都可以作为vector迭代器(vector迭代器就是普通指针)

template<class T,class Alloc=alloc>

class vector{

public:

typedef  T  value_type;

typedef   value_type*   iterator;

};

vector<int>::iterator iiter等价于int * iiter;

vector数据结构

线性连续空间

template<class T,class Alloc=alloc>

class vector{

protected:

iterator start;//目前使用空间的头

iterator end;//目前使用空间的尾

iterator end_of_storage;//目前可用空间的尾

};

vector的成员函数:size()和capacity()区别在于:

size()返回的是finish-start(里面的元素个数),而capacity()返回的是end_of_storage-start(目前占有的空间大小)

一旦size()==capacity(),下次新增元素就会扩充至容量的两倍,过程如下:

1.确定申请大小,2.分配空间,3.copy元素,4.destroy并释放原空间到free-list,5.更新偏移

注:一旦空间重新配置,指向原vector的迭代器就都失效了,因为指向的原空间已经不存在

list

每次插入或者删除,就配置或释放一个元素空间

list有一个重要性质:插入不会造成原有的list迭代器失效(vector可能失效),删除操作只有指向被删除元素的迭代器失效。

list节点结构:

template <class T>

struct __list_node{

typedef void* void_pointer;

void_pointer prev;

void_pointer next;

T data;

};

list迭代器:

template<class T,class Ref,class Ptr>

struct __list_iterator{

typedef __list_iterator<T,&T,*T>
literator;

typedef __list_node<T>* link_node;

link_type
node; //指向node的节点,为了迭代器遍历(一开始指向尾端的空白节点)

};

list的数据结构:

SGI list是一个环状双向链表,只需一个指针,就能遍历整个链表

deque

deque是双向开口的连续线性空间,vector是单向开口的连续线性空间

vector和deque对比:

1.deque允许常数时间内对头端进行元素的插入或移除

2.deque没有capacity概念,它的结构是分段连续空间组合而成,随时增加一段新的空间并链接起来,

由于第二点,deque的迭代器不是普通指针,复杂度很高,所以非必要的话,尽量使用vector,

如果需要对deque进行排序,为了最高效率,1.deque先复制到vector中,2.vector排序(STL的sort算法)3.复制回deque

deque中控器:

deque是逻辑上的连续空间,由一段一段的定量连续空间构成,

deque最大任务就是维护其整体连续的假象,避开了vector“重新配置,复制,释放”的轮回,代价是复杂的迭代器架构

deque采用一块所谓的map作为主控(map是一小块连续空间,每个map节点指向一块较大的连续线性空间,缓冲区(deque存储主体))

默认
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: