顺序容器——vector

1、vector定义及概述

vector与array非常相似,唯一的区别在于灵活性,数组是静态空间,一旦定义就不能改变,变大变小都需要客户端自己重新配置新的空间,然后将元素从旧址搬到新址,再把原来的空间还给系统。

vector是动态空间,随着元素的加入,他的内部机制会自行扩充空间以容纳新元素。

1.vector的底层实现

vector所采用的是一个连续的线性空间,以两个迭代器start和finish分别指向连续空间中已被使用的空间的头和尾,以迭代器end_of_storage指向整个连续空间的尾部(包括备用空间)。

template <class T, class Alloc = alloc>  //vector默认使用alloca作为空间配置器
class vector {
···
protected:
  iterator start;          // 表示目前使用空间的头
  iterator finish;         // 表示目前使用空间的尾
  iterator end_of_storage; // 表示目前可用空间的尾
...
}

为了降低空间配置时的速度成本,vector实际配置的大小通常比客户端的需求更大一些,以便将来可能的扩充。

2.vector的初始化

vector<T> v1                 // 默认初始化, 此时v1为空。
vector<T> v1(v2)              // 执行的copy初始化,此时v1与v2的内容相同
vector<T> v1 = v2           // 与上面相同,都会执行copy构造函数
vector<T> v1(n)              // 此时v1的size大小为n ,它里面的值是根据T的类型进行默认初始化的
vector<T> v1(n, a)           // v1的初始化为n个值为a的元素
vector<T> v1{a, b, c}       // 列表初始化,v1内现在的元素就是a, b, c 
vector<T> v1 = {a, b, c}    // 列表初始化,v1内现在的元素就是a, b, c

3.vector的常用操作

temple <class T,class Alloc=alloc>
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); //返回尾部元素的引用
}
除了上面说到的begin和end之外,还有rbegin和rend
v.rbegin()返回的是一个指向容器的最后一个元素逆序迭代器
v.end()返回的是一个指向容器中第一个元素的上一个位置的逆序迭代器
查看容器大小的操作还有max_size()和resize()
v.max_size()返回容器中可容纳最多的元素个数
v.resize(n) 调整容器v的长度大小,使其能容纳n个元素,若n<v.size(),则删除多出来的长度
v.resize(n,t) 调整容器v的大小,使其能容纳n个元素,所有新添的元素值初始化为t

4.vector的插入和删除


v.push_back(t)//在容器尾部插入一个元素t,时间复杂度为O(1)
void push_back(const T& x)
{
	if(finish!=end_of_storage-begin)//判断是否还有备用空间
	{
		construct(finish,x); //直接在备用空间中插入元素
		++finish;  //调整尾部位置
	}
	else    //没有备用空间则扩容
	{
		insert_aux(end(),x);
	}
}
v.insert(p,x)//在迭代器p所指向的元素前插入新元素x,返回指向新元素的迭代器
iterator insert(iterator position,const T& x)
{
	size_type n=position-begin();
	if(finish!=end_of_storage-begin&&position==end())
	{
		construct(finish,x);
		++finish;
	}
	else
	{
		insert_aux(position,x);
		return begin()+n;
	}
}
v.insert(p,n,x)//在迭代器p所指向的元素前插入n个初始化为x的元素
void insert(iterator pos,int n,const T& x)
{
	insert(pos,(size_type)n,x);
}
v.insert(p,f,l)//在迭代器p所指向的元素前插入f和l之间的元素
temple <class InputIterator>
void insert(iterator position, InputIterator first, InputIterator last)
{
  range_insert(position, first, last, iterator_category(first));
}

v.erase(p)//删除迭代器p指向的元素,返回一个指向被删除元素后面的元素,
如果配置项容器的最后一个元素,则返回的迭代器指向超出末端的下一个位置,
如果p本身就是超出容器末端的下一个位置,则该函数未定义
iterator erase(iterator position)
{
	if(position+1!=end())
		copy(position+1,finish,position);
	--finish;
	destroy(finish);
	return position;
}
v.erase(f,l)//删除f到l之间的所有元素,返回一个迭代器,它指向被删除元素段后面的元素。  
              如果l本身就是指向超出容器末端的下一个位置,
              则返回的迭代器也指向容器末端的下一个位置
iterator erase(iterator f,iterator l)
{
	iterator i=copy(l,finish,f);
	destroy(i,finish);
	finish=finish-(l-f);
	return f;
}
v.clear()//删除容器中能够所有元素
{
	erase(begin(),end());
}

v.pop_back()//删除容器中的最后一个元素
void pop_back()
{
	--finish;//将尾端标记往前移一格
	destroy(finish);
}

2.vector的扩容机制

  1. 倍数开辟更大的内存
  2. 旧的数据拷贝到新的内存
  3. 释放旧内存,指向新内存

3.vector的优缺点

  • 优点:支持快速的尾部插入和删除

  • 缺点:任意位置插入和删除的时间复杂度高

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值