栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

深入理解vector

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

深入理解vector

深入理解vector
  • vector概述
  • vector的迭代器
  • vector的数据结构
  • vector的构造与内存管理
  • vector的元素操作

vector概述

vector的数据安排以及操作方式与array非常相似,两者的唯一差别在于空间的运用的灵活性,array是静态空间,一旦配置了就不能改变,vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间以容纳新元素

vector的迭代器

vector维护的是一个连续线性空间,所以不论其元素型别为何,普通指针都可以作为vector的迭代器而满足所有必要条件,所以vector提供的是Random Access Iterators

template 
class vector
{
	typedef T value_type;
	typedef value_type* iterator;
};
vector的数据结构

vector所采用的数据结构非常简单:线性连续空间。它以两个迭代器start和finish分别指向配置得来的连续空间中目前已被使用的范围,并以迭代器end_of_storage指向整块连续空间的尾端:

template 
class vector
{
protected:
	iterator start;
	iterator finish;
	iterator end_of_storage;
};

运用start,finish,end_of_storage三个迭代器,便可轻易地提供首尾标示,大小,容量,空容器判断,注标([])运算子等功能

template 
class vector
{
public:
	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() 
	{
		return *begin();
	}
	reference back()
	{
	 	return *(end()-1);
	}
};
vector的构造与内存管理

vector提供许多constructs,其中一个允许我们指定空间大小及初值:

//构造函数,允许指定vector大小n和初值value
vector(size_type n,const T& value)
{
	fill_initialize(n,value);
}

//填充并予以初始化
void fill_initialize(size_type n,const T& value)
{
	start =allocte_and_fill(n,value);
	finish=start+n;
	end_of_storage=finish;
}
//配置而后填充
iterator allocate_and_fill(size_type n,const T& x)
{
	iterator result=data_allocator::allocate(n);
	unititalized_fill_n(result,n,x);
	return result;
}

当我们以push_back()将新元素插入到vector尾端时,该函数首先检查是否还有备用空间,如果有就直接在备用空间上构造元素,并调整迭代器finish,使vector变大,如果没有备用空间了,就扩充空间(重新配置,移动数据,释放空间)

void push_back(const T& x)
{
	if(finish!=end_of_storage)
	{
		construct(finish,x);
		++finish;
	}
	else
		insert_aux(end(),x);
}
template 
void vector::insert_aux(iterator position,const T& x)
{
	if(finish!=end_of_storage)//还有备用空间
	{
		//在备用空间起始构造一个元素,并以vector最后一个元素值为其初值
		construct(finish,*(finish-1));
		//调整水位
		++finish;
		T x_copy=x;
		copy_backward(position,finish-2,finish-1);
		*position=x_copy;
	}
	else
	{
		const size_type old_size=size();
		const size_type len=old_size!=0?2*old_size:1;
		//以上配置原则:如果原大小为0,则配置1个元素大小
		//如果原大小不为0,则配置原大小的两倍
		//前半段用来放置原数据,后半段准备用来放置新数据
		iterator new_start=data_allocator::allocate(len);
		iterator new_finish=new_start;
		try
		{
			new_finish=uninitialized_copy(start,position,new_start);
			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;	
	}
}

所谓的动态增加大小,并不是在原空间之后接续新空间(因为无法保证原空间之后尚有可供配置的空间),而是以原大小的两倍另外配置一块较大空间,然后将原内容拷贝过来,然后才开始在原内容之后构造新元素,并释放原空间,因此,对vector的任何操作,一旦引起空间重新配置,指向原vector的所有迭代器都失效了

vector的元素操作
//将尾端元素拿掉,并调整大小
void pop_back()
{
	--finish;//将尾端标记前移一格,表示将放弃尾端元素
	destroy(finish);
}
//清除[first,last)中的所有元素
iterator erase(iterator first,iterator last)
{
	iterator i=copy(last,finish,first);
	destroy(i,finish);
	finish=finish-(last-first);
	return first;
}


下面是vector::insert()实现内容:

//从position开始,插入n个元素,元素初值为x
template 
void vector::insert(iterator position,size_type n,const  T& x)
{
	if(n!=0)//当n!=0,才进行以下所有操作
	{
		if(size_type(end_of_storage-finish)>=n)//备用空间大于等于新增元素个数
		{
			T x_copy=x;
			const size_type elems_after=finish-position;
			iterator old_finish=finish;
			if(elems_after>n)//插入点之后的现有元素个数大于新增元素个数
			{
				uninitialized_copy(finish-n,finish,finish);
				finish+=n;
				copy_backward(position,old_finish-n,old_finish);
				fill(position,position+n,x_copy);
			}	
			else//插入点之后的现有元素个数小于等于新增元素个数
			{
				uninitialized_fill_n(finish,n-elems_after,x_copy);
				finish+=n-elems_after;
				uninitialized_copy(position,old_finish,finish);
				finsih+=elems_after;
				fill(position,old_finish,x_copy);			}
		}
	}
	else
	{
		//备用空间小于新增元素个数(那就必须配置额外的内存)
		//首先决定新长度:旧长度的两倍,或旧长度+新增元素个数
		const size_type old_size=size();
		const size_ype len=old_size+max(old_size,n);
		//以下配置新的vector空间
		iterartor new_start=data_allocator::allocate(len);
		iterator new_finish=new_start;
		_STL_TRY
		{
			//以下首先将旧vector的插入点之前的元素复制到新空间
			new_finish=uninitialized_copy(start,position,new_start);
			//以下再将新增元素填入新空间
			new_finish=uninitialized_copy_n(new_finish,n,x);
			new_finish=uninitialized_copy(psition,finish,new_finish);
			
		}
	}
#ifdef _STL_USE_EXCEPTIONS
	catch(...)
	{
		destroy(new_start,new_finish);
		data_allocator::deallocate(new_start,len);
		throw;
	}
#endif
	destroy(start,finish);
	deallocate();
	deallocate();
	start=new_start;
	finsih=new_finish;
	end_of_storage=new_start+len;
	}
  }	
}



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1014074.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号