vector的介绍
vector在C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。
- vector是表示可以改变大小的序列容器
- 可以像数组一样使用。采用连续的存储空间存储元素,支持元素的随机访问,但是又不像数组,可以动态自动扩容。(vs下1.5倍增容,g++下2倍增容)
- vector使用动态分配数组存储它的元素,当新插入一个元素时,如果空间不够,则会分配一个新的数组,将全部元素移动到新数组。(代价较高)
- vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是常数时间的复杂度完成的。
- vector占用了更多的存储空间,未来获得管理存储空间的能力,并且以一种有效的方式动态增长
- 与其他动态序列容器相比(deques,lists),vector在访问元素的时候更加高效,在末尾添加和删除相对高效。对于其他不在末尾的删除和插入操作,效率更低。
reserve和resize
void resize (size_type n, value_type val = value_type());
-
如果n小于当前容器的大小,则将内容减少到其前n个元素,并删除超出范围的元素(并销毁它们)。
-
如果n大于当前容器的大小,将自动重新分配已分配的存储空间。通过在末尾插入所需数量的元素来扩展内容,以达到n的大小。如果指定了val,则将新元素初始化为val的副本,否则将对它们进行值初始化。
void reserve (size_type n);
- 如果n大于当前向量容量,则该函数使容器重新分配其存储,将其容量增加到n(或更大)。
- 如果n小于容器的容量则不会影响size和capacity的值
vector的模拟实现
#include <assert.h>
#include <iostream>
#include <algorithm>
#include <math.h>
using namespace std;
namespace lhy
{
template<class T>
class vector
{
public:
typedef T* iterator;
typedef const T* const_iterator;
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
const_iterator cbegin()
{
return _start;
}
const_iterator cend()
{
return _finish;
}
size_t size()
{
return _finish-_start;
}
size_t capacity()
{
return _endofstroge-_start;
}
//无参构造
vector()
:_start(nullptr)
,_finish(nullptr)
,_endofstroge(nullptr)
{}
vector(int n,const T& val=T())
:_start(nullptr)
,_finish(nullptr)
,_endofstroge(nullptr)
{
reserve(n);
iterator end=_start;
while(end!=_endofstroge)
{
push_back(val);
++end;
}
}
vector(vector<T>&v)//拷贝构造
:_start(nullptr)
,_finish(nullptr)
,_endofstroge(nullptr)
{
reserve(v.capacity());
iterator it=_start;
const_iterator vit=v.cbegin();
while(vit!=v.end())
{
*it++=*vit++;
}
_finish=_start+v.size();
_endofstroge=_start+v.capacity();
}
~vector()
{
delete[] _start;
_start=_finish=_endofstroge=nullptr;
}
T& operator[](size_t pos)
{
return _start[pos];
}
void resize(int n,const T& val=T())//T()为默认构造 int的内置类型默认为0
{
//空间不够则扩容,并赋值缩小空间则改变_finish
if(n<size())
{
_finish=_start+n;
return;
}
if(n>capacity())
{
reserve(n);
}
iterator end=_finish;
while(end!=_start+n)
{
*end=val;
++end;
}
//重置一下_finish
_finish=_start+n;
}
void reserve(size_t n)
{
//如果n>capacity则需要增容,创建一个新的大小为n的空间,将原有的数据拷贝到新空间,
//然后将_start,_finish,_endofstroge重置
if(n>capacity())
{
T* tmp=new T[n];
if(_start)
if(_start)
memcpy(tmp,_start,sizeof(T)*size());
_finish=tmp+size();
_start=tmp;
_endofstroge=_start+n;
}
}
iterator insert(iterator pos,const T& val)
{
assert(pos<=_finish);
//空间不够则扩容,扩容需要重置一下pos,在pos位置插入需要将pos之后的向后移动
if(_finish==_endofstroge)
{
size_t n=pos-_start;
size_t newcapacity=((capacity()==0)? 2:capacity()*2);
reserve(newcapacity);
pos=_start+n;
}
iterator end=_finish-1;
while(end>=pos)
{
*(end+1)=*end;
--end;
}
*pos=val;
++_finish;
return pos;
}
iterator erase(iterator pos)
{
assert(pos<_finish);
iterator end=pos+1;
while(end!=_finish)
{
*(end-1)=*(end);
++end;
}
--_finish;
return pos;
}
void push_back(const T&val)
{
insert(_finish,val);
}
void pop_back()
{
erase(--_finish);
}
void _swap(vector<T>& v)
{
swap(_start,v._start);
swap(_finish,v._finish);
swap(_endofstroge,v._endofstroge);
}
void print(vector<T> &v)//这个是方便测试打印用的
{
vector<T>:: iterator it=v.begin();
for(auto e: v)
{
cout<<e;
}
cout<<endl;
}
private:
iterator _start;
iterator _finish;
iterator _endofstroge;
};
}
void test1()
{
lhy::vector<int>s1;
lhy::vector<int>s2(3,4);
lhy::vector<int>s3(s1);
s1.push_back(1);
s1.push_back(2);
s1.push_back(3);
s1.push_back(4);
s1.insert(s1.begin()+0,5);
s1.resize(20);
s1.reserve(30);
cout<<s1.capacity()<<endl;
s1.erase(s1.begin()+1);
s1._swap(s2);
lhy::vector<int>:: iterator it=s1.begin();
while(it!=s1.end())
{
std::cout<<*it;
++it;
}
cout<<endl;
s2.print(s2);
}
void test2()
{
lhy::vector<int>s1(5,2);
lhy::vector<int>:: const_iterator it=s1.cbegin();
while(it!=s1.cend())
{
std::cout<<*it;
++it;
}
cout<<endl;
}