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;
}
衍生:表示内涵关系,例如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;
}
相关文章推荐
- STL源码剖析_读书笔记:第四章 序列式容器 list篇
- STL源码剖析_读书笔记:第四章 序列式容器 stack篇
- STL源码剖析_读书笔记:第四章 序列式容器 queue篇
- 《STL源码剖析》深入分析序列式容器——vector
- STL 源码剖析读书笔记三:序列式容器之 vector、list
- 《STL源码剖析》读书笔记之序列式容器(3)
- 《STL源码剖析》读书笔记——(2)序列式容器
- 《STL源码剖析》-序列式容器(一)vector容器
- STL源码剖析-序列式容器之vector
- 《STL源码剖析》-序列式容器(一)vector容器
- 《STL源码剖析》读书笔记---第4章 序列式容器
- STL源码剖析(四)序列式容器(vector,list)
- 《STL源码剖析》学习笔记之三——序列式容器(list和vector)
- STL源码剖析 - 第4章 序列式容器 - vector
- Chapter 4: 序列式容器之 vector
- STL容器-序列式容器vector
- 《Spring揭秘》第四章 读书笔记 —— Spring的IoC容器之BeanFactory
- 《stl源码剖析》--序列式容器
- STL源码剖析 - 第4章 序列式容器 - list
- STL源码剖析-序列式容器之list和slist