您的位置:首页 > 其它

STL源码剖析_读书笔记:第四章 序列式容器 vector篇

2013-10-04 23:03 399 查看
数据结构:研究数据排列,利于查找或排序等目的的学科

衍生:表示内涵关系,例如map中含有RB-tree

序列式容器含义:元素都可排序但未必有序



Vector:动态空间,自扩充。吃多少用多少。因为支持随机存取,所以提供Random Access Iterators。普通指针可以作为vector的迭代器。vector<int>::iterator
iter,则iter类型为int *



Vector数据结构:

迭代器start和finish执行已经被使用的范围,end_of_storage表示可用空间的尾部

容量:用于扩充,>=vector的大小



动态增加大小的原理:

取原大小两倍空间,拷贝原容器内容至新空间,并释放原空间



Inset(position,n,x):函数思路:

1)若备用空间>=新增元素个数,(1)若插入点后现有元素个数>新增元素个数,则将插入点后的所有元素放到储备空间的最后面,然后在插入点后插入新增元素;(2)若插入点后现有元素个数<=新增元素个数,则先在储备空间中复制若干元素,然后将插入点后的老元素复制到储备空间的后面,腾出的地方插入新元素

2)若备用空间<新增元素个数,分配额外内存为原内存两倍。将旧vector插入点之前元素复制到新空间,将新增元素复制到新空间,将旧v ector插入点之后元素复制到新空间



下面的程序是关于vector的部分重要函数的实现

#include<iostream>

#include<string>

#include<vector>

#include<iterator>

using namespace std;

//填充并初始化

template<class size_type>

void fill_initialize(size_type n,const T& value)

{

start = allocate_and_fill(n,value);

finish = start + n;

end_of_storage = finish;

}

template<class size_type>

iteratir allocate_and_fill(size_type n,const T& value)

{

iterator result = data_allocator::allocate(n);//分配n个元素空间

unintialized_fill_n(result,n,x);//根据型别使用STL算法或是逐一构造

return result;

}

//template<class Iterator,class size_type,class reference,class T,class Alloc = alloc>

template<class T,class Alloc = alloc>

class MaVector

{

public:

MaVector(size_type n,const T& value){fill_initialize(n,value);}

iterator begin(){return start;}

iterator end() {return finish;}

size_type size() const {return size_type(end() - begin());}

size_type capacity() const {return size_type(end_of_storage-begin());}

bool empty() const {return begin()==end();}

reference operator[](size_type n){return *(begin()+n);}

reference front(){retun *begin();}

reference back(){return *(end()-1);}

void push_back(const T& x)//检查备用空间,若没有,扩充

{

if(finish!=end_of_storage)

{

construct(finish,x);

++finish;//调整水位高度

}

else//无备用空间

{

insert_aux(end(),x);

}

}

void insert_aux(iterator position,const T& x)

{

if(finish!=end_of_storage)//还有备用空间

{

construct(finish,*(finsh-1));//用vector最后一个元素构造元素

++finish;

T x_copy = x;

copy_backward(position,finish-2,finish-1);

*position = x_copy;

}

else//无备用空间

{

const size_type old_size = size();

const len = old_size!=0 ? 2*old_size:1;//配置两倍的原内存空间,前半段放原数据,后半段放新数据

iterator new_start = data_allocator::allocate(len);

iterator new_finish = new_start;

try

{

//将原vector内容拷贝到新vector

new_finish = uninitialized_copy(start,position,new_start);

//为新元素设定初值x

construct(new_finish,x);

++new_finish;

//将原vector备用空间内容也拷贝过来

new_finish = uninitialized_copy(position,finish,new_finish);

}

catch(...)

{

destroy(new_start,new_finish);

data_allocator::deallocate(new_start,len);

throw

}

//析构并释放原vector

destroy(begin(),end());

deallocate();

//调整迭代器,指向新vector

start = new_start;

finish = new_finish;

end_of_storage = new_start+len;

}

}

//先调整大小再拿掉末尾元素

void pop_back()

{

--finish;

destroy(finish);

}

//清楚[first,last)中所有元素

iterator erase(iterator first,iterator last)

{

iterator i = _copy(last,finish,first);

destroy(i,finish);

}

iterator erase(iteraor position)

{

if((position+1)!=end())

{

copy(position-1,finish,position);

}

--finish;

destroy(finish);

return position;

}

void clear(){erase(begin(),end());}

protected:

iterator start; //使用空间头部

iterator finish; //使用空间尾部

iterator end_of_storage;//可用空间尾部

typedef simple_alloc<value_type,Alloc> data_allocator;//以元素大小为配置单位

};

void show(vector<int>& iv)

{

cout<<"size:"<<iv.size()<<endl;

cout<<"capacity:"<<iv.capacity()<<endl;

}

int main(int argc,char *argv[])

{

int i;

vector<int> iv(2,1);

show(iv);

iv.push_back(2);

show(iv);

iv.push_back(3);

show(iv);

iv.push_back(4);

iv.clear();

show(iv);

show(iv);

getchar();

return 0;

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