重读STL源码剖析:vector

vector

数据结构:

三个数据成员:

iterator start;//指向vector目前使用空间头,即vector.begin()

iterator finish;//指向vector目前使用空间尾,即vector.end()

iterator end_of_storage;//指向vector目前可用空间尾

重要函数:

begin():return start;

end():return finish;

size():return size_type(end()-begin());//size_type类似于value_type

capacity():return end_of_storage-start;

resize():

首先判断新的大小是否小于原大小,如果小于size(),则将new_size之后的元素抹去

否则在end()后补齐缺少的元素

void resize(size_type new_size,const T&x)
{
	if(new_size<size())
		erase(begin()+new_size,end());
	else
		insert(end(),new_size-size(),x);
}

clear():erase(begin(),end());//只析构,不释放空间  

push_back():

首先判断空间是否可用,如果可用,则在finish处构造,并将finish后移;

如果不可用,则调用insert_aux搬移,下面具体介绍insert_aux();

void push_back(const T& x)
{
	if(finish!=end_of_storage){
		construct(finish,x);
	++finish;
	}
	else
		insert_aux(end(),x);
}

  

insert_aux()

代码在P122页

具体流程:

首先判断当前是否还有容量(finish!=end_of_storage),如果还有容量,则将[position,finish)的元素整体后移一个,在原position上插入新元素,同时将finish向后移。

如果没有容量,则首先计算新空间大小(为原来的2倍),并在开辟对应大小的新空间。

开辟完成后将原来的元素拷贝到新空间,拷贝完成后析构源空间的元素并释放空间,重新调整三个迭代器start,finish与end_of_storage

 

pop_back()

pop_back()只是将finish前移并析构原back()的元素,并不释放空间

void pop_back()
{
  --finish;
  destory(finish);
}

  

erase()

要删除的部分为[first,last),则首先将[last,finish)的元素复制到first及以后,然后清除覆盖区域以后的元素,也就是[i,finish)

然后将finish移动到覆盖位置的尾端,返回插入位置的新元素

iterator erase(iterator first,iterator last)
{
	iterator i=copy(last,finish,first);
	destroy(i,finish);
	finish=finish-(last-first);
	return first;
}

  

insert()

书上P125

首先判断备用空间大小,如果大于或等于新增元素个数,则可以进行插入。

此时:

首先判断插入点之后的元素个数,如果插入点元素个数大于新增元素个数,则:

首先将[finish-n,finish)的元素移动到finish之后(共n个元素),更新finish,然后将[position,old_finish-n)的元素移动到old_finish及之后(共m-n个元素),这样position~old_finish共m个元素都移动完毕,并腾出了n个元素的空间。再在[position,position+n)上覆盖新的元素。

如果小于新增元素个数,则:

首先在finish及之后的n-m个位置上生成插入元素,共n-m个。

然后将position~old_finish共m个元素移动到新的尾部,这样腾出了m个元素空间。

再在postition~old_finish上写入插入元素,共m个,则n-m+m=n,插入完成。

 

如果空间不足:

首先决定空间大小:len=old_size+max(old_size,n);//新长度要么扩容两倍能装下,如果装不下则要扩容到old_size+n刚好装下

然后为新元素分配空间

再然后将原来插入点之前的元素复制到新空间,再填入n个插入元素,再将原来插入点之后的元素复制到新空间。

然后析构原来空间的元素,并释放空间。

最后调整三个迭代器指向新空间的位置

posted @ 2019-09-03 21:06  李湘沅  阅读(212)  评论(0编辑  收藏  举报