一、vector基本介绍
vector属于STL(标准模板库)的六大组件之一容器部分,它类似于数组。具体有以下几个特点:
1、动态可变,即一个可变大小数组的序列容器;
2、类似于数组,vector采用的连续存储空间来存储元素,即可用下标对vector的元素进行访问,和数组一样高效;
3、vector使用动态分配数组来存储它的元素。当有新的元素插入时,为了增加存储空间,这个数组会被重新分配大小。具体做法是:分配一个新的数组,然后将全部元素移到这个数组中 ;
4、vector空间分配策略:vector会分配一些额外的空间来适应可能的增长,因为存储空间比实际需要的存储空间更大,不同的库分配策略不相同;但是重新分配都是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数的时间复杂度内完成的。
5、与其他动态序列容器相比较,vector在末尾插入和删除的效率更高,其他位置效率略低。
三、vector的声明及初始化
以下是vector的一些常用初始化及声明方式
vector<int> a //声明一个int型变量a
vector<int> a(20) //声明一个int型,大小为20的变量a
vector<int> a(20,1) //声明一个初始大小为20,初始值都为1的变量a
vector<int> b(a) //声明一个用a去初始化的变量b
vector<int> b(a.begin(),a.begin()+3) //将变量a中从第0个到第2个(共三个)作为b变量的初始值
当然还可以用数组来初始化
int a[] = { 1, 2, 3, 4, 5 };
vector<int> v(a, a+sizeof(a) / sizeof(int));
注:v(a, a+sizeof(a) / sizeof(int))相当于v(a.begin(),a.end());所以要用a首元素的地址+size去找到末尾元素的地址
二、基本接口的模拟实现请看下篇啦~~~~
三、vector空间增长
1、capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的;
#include <iostream>
#include <vector>
using namespace std;
int main()
{
size_t sz;
vector<int> array;
sz = array.size();
cout << "空间增长:" << endl;
for (int i = 0; i < 100; i++)
{
array.push_back(i);
if (sz != array.capacity())
{
sz = array.capacity();
cout << "capacity changed:" << sz << endl;
}
}
system("pause");
return 0;
}
vs下运行结果:
g++运行结果:
注意:1、reserve只负责开空间,如果确定vector要用多少空间,reserve可以缓解vector增容的代价;
2、resize在开空间的时候还会进行初始化,直接影响到size.
四、vector迭代器失效问题
int main()
{
int a[] = { 1, 2, 3, 4, 5 };
vector<int> v(a, a+sizeof(a) / sizeof(int));
//使用find查找到3所在位置的iterator
vector<int>::iterator pos = find(v.begin(), v.end(), 3);
//删除pos位置的数据,导致pos迭代器失效
v.erase(pos);
//非法访问
cout << *pos << endl;
//在pos位置插入数据,导致pos迭代器失效
pos = find(v.begin(), v.end(),3);
v.insert(pos, 30);
cout << *pos << endl;
system("pause");
return 0;
}
以上代码在erase和insert的时候导致vector迭代器失效,下图为为何失效做出解释
为避免迭代器失效,erase和insert在底层是这样实现的:
iterator Erase(iterator pos)
{
iterator begin = pos + 1;
while (begin != _finish)
{
*(begin - 1) = *begin;
++begin;
}
--_finish;
//返回的是pos的下一个位置
return pos;
}
iterator Insert(iterator pos, const T& x)
{
assert(pos <= _finish);
if (_finish = _endofstorage)
{
size_t size = Size();
size_t newcapacity = Capacity == 0 ? 1 : Capacity() * 2;
Reserve(newcapacity);
//重置pos
pos = _start + size;
}
iterator end = _finish - 1;
while (end >= pos)
{
*(end + 1) = *end;
--end;
}
*pos = x;
++_finish;
return pos;
}