1. vector的介绍和使用
- vector是表示可变大小数组的序列容器。
- 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。
- 本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。
- vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。
- 因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长。
- 与其它动态序列容器相比(deques, lists and forward_lists), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起lists和forward_lists统一的迭代器和引用更好。
更为详细的可以查看vector文档介绍。
2. vector的模拟实现
vector的嵌套型别定义
typedef _Ty value_type;
typedef value_type* iterator;
typedef value_type& reference;
typedef size_t size_type;
vector的成员变量
private:
iterator _start;
iterator _last;
iterator _end;
2.1 vector构造函数和拷贝构造函数
vector():_start(nullptr),_last(nullptr),_end(nullptr)
{}
vector(size_type n,const _Ty& value):_start(nullptr),_last(nullptr),_end(nullptr)
{
insert(n,value);
}
vector(iterator f,iterator l):_start(nullptr),_last(nullptr),_end(nullptr)
{
insert(f,l);
}
vector(const vector<int>& iv)
{
reserve(iv.capacity());
iterator it = begin();
iterator vit = iv.end();
while (vit != iv.begin())
{
*it++ = *vit--;
}
}
2.2 insert函数和eraser函数
iterator insert(iterator pos,const _Ty& value)
{
//1.当size()==capacity()时,表明vector已满,再进行插入前需要进行扩容
if(size()== capacity())
{
size_type oldpos = pos - begin();
//这里需要防止一种情况:若vector为空的时候,他的capacity为0,这个时候给他直接扩容2倍是行不通的,
//因为2*0 = 0,因此就需要进行判断
size_type newcapacity = (capacity() == 0)? 1 : 2*capacity();
reserve(newcapacity);
//这里空间发生了变化,pos迭代器会失效,因此需要重新对pos进行设置
//reserve不会使vector的成员变量失效
pos = begin() + oldpos;
}
//2.当size() < capacity()时,表明vector未满,插入直接在pos的位置进行插入
//需要注意的是插入是在pos指向的位置进行插入,并且插入需要挪动数据,
//将pos位置之后的数据全部向后挪动一个,为防止元素被改写,则需要从后向前进行挪动
iterator tail = _last;
while(tail > pos)
{
*tail = *(tail-1);
--tail;
}
//这里要注意的是挪动数据时,因为没有对pos位置进行操作,所以pos位置的迭代器并没有失效,
//但是pos位置之后的迭代器全部失效了,但在这里并没有关系,我们并不会用到那些迭代器
*pos = value;
//插入完之后,一定要对_last指针+1,因为全部向后挪动了一个元素
++_last;
return pos;
}
void insert(size_type n,const _Ty& value)
{
for(int i = 0;i < n; ++i)
{
insert(end(),value);
}
}
void insert(iterator f,iterator l)
{
while(f!=l)
{
insert(end(),*f);
++f;
}
}
iterator erase(iterator pos)
{
assert(pos >= _start || pos < _last);
//1.删除pos位置的元素,就是将[pos,end()]这个区间向前挪动一个即可
iterator it = pos + 1;
while(it != _last)
{
*(it-1) = *(it);
++it;
}
--_last;
return pos;
}
2.3 reserve函数和resize函数
void reserve(size_type n)
{
//若 n 的值大于vecto6RТТB'B&WGW&Zh.iyNXJ~K6GyNi{nX >yJ&W6W'fRX{[kZxbwC66GТТ&W6W'fRТ^[NXJ~KR6GyNi{nX [eNyNh([XX ТFW&FBCТB'BТvBBТТBfSТCТ6RX{[Khh^[K>YZKiXyNzТТfW66fRТТ'BVRТf6ТТW&6RVТТ РТFW&F'BFW&FfRТТ[6R66Gi{ni7F.khXhhZb6R66GТТ6UR&VvТxΙh.jKzx8^Xk^WfV7FzyNi{nX nyF66GKKi{nX {KnyNhZX yNK"j[hXNijТ6UR66G66Gb3c3"66GРТ&W6W'fR66GРТx{NXKnX>YKZKiXjhxkZТ6W'f^KKfV7FNhYXZKiXТ&Vv[6Rf66Gi{ni7Fk.XZ^yNhNK{hТhk:hH^i>hY yNK{hnKNhhhXi[hgKYNi[hXZ:Y YXKK.jXX>{J*iKXihKXhXТFW&FCТvFfwCТFFТFТxhk:hHi[hi{nKk*iZK{i8KWyNY[nk*iZKiXniK{KYNYXZ:ZKiXKnnY[nk*iX[>{;KnKyJX*>KYТfSРТ.XZ^ZYZ鮊hZ7Nh(KXZ:Y YXKnKKXX>{J ТCРТ&WGW&Тf'B6URfRТТffТТ'BVRТf'BFW&FFW&FТТvbТТ'BVbТcТРТFW&F&6RFW&FТ76W'BwC'BBТXGyNXX>{JiX{NY XXKKXXFW&FBТvBBТТBBТCТТCТ&WGW&ТТ РТ РТ&fFSТFW&F7F'CТFW&F7CТFW&FVТРЧРЧfFW7CЧТFW7CfV7FCwCcРТ6ff&bR"ffbRffVТ6ff&b6G"ffb6GffVТb6Тb6"Тb62Тb6BТ6ff&bR"ffbRffVТ6ff&b6G"ffb6GffVРТFW7CfV7FCwCFW&FBbvРТvBbBТТ6ffBff"#ТCТ6ffVТbТbТBbvТvBbBТТ6ffBff"#ТCТ6ffVРРЧЧfFW7C"ЧТFW7CfV7FCwCb ТFW7CfV7FCwCFW&FBbvТvBbBТТ6ffBff"#ТCТ6ffVЧЧfFW7C2ЧТ%ТFW7CfV7FCwCb""bТFW7CfV7FCwCFW&FBbvТvBbBТТ6ffBff"#ТCТ6ffVРЧЧТFW7CТFW7C"ТFW7C2Т&WGW&ЧУ&SУFcУjX[>K5DfV7FNjhyNih~z[K{NZIyX[425DfV7F^Z{J.zKK^XNih~zhn{~{XyNyX[>ih~z[ZJ~Z^YZIiJ |