在前几篇针对于进行介绍的文章中提到了,对于,可以将其看作是一个字符数组。对于本篇文章的主题,可以将其看作数据结构中的顺序表,其大体的特点如下:
1. vector是表示可变大小数组的序列容器。
2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素
进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。
3. 本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重分配大小。
4. vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。
5. 因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式增
长。
6. 与其它动态序列容器相比(deque, list and forward_list), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起list和forward_list统一的迭代器和引用更好。
在简单了解了关于的特性后,下面将给出的相关函数,以及部分函数的使用方法
对于中的构造函数的种类如下:
vector() //无参构造
vector(size_type n, const value_type& val = value_type() //构造并初始化n个val
vector (const vector& x); //拷贝构造
vector (InputIterator first, InputIterator last); //使用迭代器进行初始化构造
在使用的相关函数之前,需要包含头文件,即:
#include
对于的无参构造较为简单,这里只给出相应的代码,不做过多解释:
int main()
{
vector v; //无参构造
return 0;
}
使用方法如下:
int main()
{
vector v(10, 1);
return 0;
}
对于,可以像一样通过不同的方式来对内容进行访问,例如:
int main()
{
vector v1(10, 1);
for (size_t i = 0; i < v1.size(); i++)
{
cout << v1[i];
}
return 0;
}
此外,在中同样可以使用迭代器对内容进行访问,这一部分内容将在下面介绍迭代器的部分统一给出。
函数的构造是利用迭代器进行构造的。例如,假设用上文中的,来构建一个新的,方法如下:
vector v2(v1.begin(), v1.end());
for (size_t i = 0; i < v2.size(); i++)
{
cout << v2[i] << ' ';
}
拷贝构造函数,具体使用如下:
int main()
{
vector v1(10, 1);
vector v2(v1.begin(), v1.end());
vector v3(v2);
cout << endl << "vector v3:";
for (auto ch : v3)
{
cout << ch << ' ';
}
return 0;
}
上图展示了中不同的迭代器,其具体使用方法如下:
int main()
{
vector v1(10, 1);
vector::iterator it1 = v1.begin();
while(it1 != v1.end())
{
cout << *it1 << ' ';
it1++;
}
return 0;
}
为了更好的演示函数的作用,此处先引入一个新的函数_,其作用可以看作顺序表中的尾插。使用_函数向中插入五个元素,即:
vector v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
通过反向迭代器对其进行访问,运行结果如下:
int main()
{
vector v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
vector::iterator it1 = v1.begin();
while (it2 != v1.rend())
{
cout << *it2 << ' ';
it2++;
}
return 0;
}
函数主要是针对于非对象,而是针对于对象。
对于二者的差距,表现为是否可以修改迭代器指向的内容,例如,对于非对象:
vector v1(10, 1);
vector::iterator it1 = v1.begin();
while(it1 != v1.end())
{
(*it1)++;
cout << *it1 << ' ';
it1++;
}
代码运行结果如下:
对于一个对象,即:
const vector v2(10, 1);
vector::const_iterator it2 = v2.cbegin();
while(it2 != v2.cend())
{
(*it2)++;
cout << *it2 << ' ';
it2++;
}
用于检测容器的容量以及内容长度,具体使用方法如下:
vector v(10,1);
cout<<"v.capacity= " << v.capacity() << endl;
cout<<"v.size= " << v.size() << endl;
运行结果如下:
对于和虽然都可以达到改变容量的效果,但是却又一定的差别
对于,假设需要将函数扩容到,即,如果,则改变容器的,不会改变。并且不会影响容器中的内容例如:
vector v(10,1);
cout<<"扩容前:"<<"v.capacity= " << v.capacity() << endl;
cout<<"扩容前:"<<"v.size= " << v.size() << endl;
v.reserve(100);
cout<<"扩容后:" << v.capacity() << endl;
cout<<"扩容后:" << v.size() << endl;
运行结果如下:
当时,函数对,,容器中的内容均不会产生影响,例如:
vector v(10,1);
cout<<"缩容前:"<<"v.capacity= " << v.capacity() << endl;
cout<<"缩容前:"<<"v.size= " << v.size() << endl;
cout << "内容:";
for (auto ch : v)
{
cout << ch << ' ';
}
cout << endl;
v.reserve(5);
cout<<"缩容后:" << v.capacity() << endl;
cout<<"缩容后:" << v.size() << endl;
cout << "内容";
for (auto ch : v)
{
cout << ch << ' ';
}
对于,假如,函数并不会影响容器的,但是会影响容器中的内容,以及容器的。为了方便演示,使用_创建以下容器:
vector v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
v1.push_back(6);
v1.push_back(7);
v1.push_back(8);
v1.push_back(9);
v1.push_back(10);
对其使用函数,代码如下:
cout << "缩容前:" << "v.capacity= " << v1.capacity() << endl;
cout << "缩容前:" << "v.size= " << v1.size() << endl;
cout << "内容:";
for (auto ch : v1)
{
cout << ch << ' ';
}
cout << endl;
v1.resize(5);
cout << "缩容后:" << v1.capacity() << endl;
cout << "缩容后:" << v1.size() << endl;
cout << "内容";
for (auto ch : v1)
{
cout << ch << ' ';
}
当时,会通过向容器的末端插入元素的方式来达到扩容的目的,并且会同时改变容器的和。并且,如果不人为给出扩容时插入的元素,则默认插入,否则插入给出的元素,例如:
cout << "缩容前:" << "v.capacity= " << v1.capacity() << endl;
cout << "缩容前:" << "v.size= " << v1.size() << endl;
cout << "内容:";
for (auto ch : v1)
{
cout << ch << ' ';
}
cout << endl;
//默认插入0
v1.resize(15);
cout << "缩容后:" << v1.capacity() << endl;
cout << "缩容后:" << v1.size() << endl;
cout << "内容";
for (auto ch : v1)
{
cout << ch << ' ';
}
如果给定末端插入元素,即:
cout << "缩容前:" << "v.capacity= " << v1.capacity() << endl;
cout << "缩容前:" << "v.size= " << v1.size() << endl;
cout << "内容:";
for (auto ch : v1)
{
cout << ch << ' ';
}
cout << endl;
v1.resize(15,1);
cout << "缩容后:" << v1.capacity() << endl;
cout << "缩容后:" << v1.size() << endl;
cout << "内容";
for (auto ch : v1)
{
cout << ch << ' ';
}
代码运行结果如下: