文章目录
前言
在上期的简单使用之后,我们并未介绍完vector中提供的所有的方法,下面即将揭开vector的神秘面纱。
(一) vector基本概念
vector是一种数据结构,与数组类似,也称单端数组,熟知的push_back()、pop_back()都是在元素的尾部进行插入和删除;
数组和vector的区别:
- vector相对于数组可以动态扩容
- vector相对于数组有一系列的函数操作
vector的逻辑图:
注:
- vc.front()和vc.back()是int类型,指的是vector容器中首尾元素本身
- vc.begin()、vc.end()、vc.rbegin()、vc.rend()都是vector*的地址,对应的就是元素的地址,可以给迭代器赋值;
(二)vector函数的使用
(1)vector的构造函数
vector<T> 变量名;
无参构造vector(const vector& vc)
拷贝构造vector(vc.begin(), vc.end());
将[vc.begin(),vc.end())的所有元素拷贝给新构造的容器vector(n, elem);
n代表个数,elem是初始化的值
(2)vector的赋值操作
vector& operator=(const vector &src);
赋值运算符的重载assign(beg, end);
[beg, end)的元素拷贝给新容器assign(n, elem);
n个elem的赋值
(3)vector的容量和大小
empty();
判断容器是否为空capacity();
返回容器的容量size();
返回容器中的元素个数resize(int num);
重新改变容器的元素个数,个数变多num>size(),使用默认值0填充新位置;若变短num<size() ,超出长度的元素被删除,但是容量不会变resize(int num, elem);
同上,只不过超出num>size()的情况使用elem进行填充
(4)vector的插入删除操作
push_back(elem);
尾插pop_back();
尾删insert(const_iterator pos, elem);
迭代器指向的pos位置,插入元素eleminsert(const_iterator pos, int count, elem);
迭代器指向的pos位置插入count 个elemerase(const_iterator pos);
删除迭代器指向位置的元素erase(const_iterator start, const_iterator end);
删除迭代器指向start~end位置的元素clear()
清空容器
(5)vector的数据存取
at(int index)
返回索引 index所值的数据operator[]
返回索引 index 所指的数据front()
返回容器中第一个数据元素back()
返回容器中最后一个数据元素
(6)vector的互换容器
vc2.swap(vc1);
-
功能:
实现两个vector容器之间数据的交换(不仅是容器中的每一个元素,还包括容器的长度、容量) -
实际功能:收缩内存空间
假设vc.capacity()容器的容量非常大,但只存储了很少的元素,那如果一直使用vc的话是不是很吃内存空间呢
所以,我们的思路就是定义一个新容器,拥有较小的容量,并且能够存储vc的中的元素,然后丢弃原来的vc容器就好了。
- 这里我们使用了匿名对象:
vector<int> (vc).swap(vc);
这句代码的意思就是使用vc拷贝构造一个匿名对象来与vc容器进行元素数据交换。匿名对象容器保存着vc原有的大容量,但是这句执行完毕后匿名对象就会被析构,被系统释放。而对于vc来说,保存着匿名对象的长度和容量;
注:
swap先交换容器中的每一个元素,再交换容器的长度,容量大小;由于容器的元素的增加都可能导致动态扩容,只有元素交换完成,才能确定当前容器的长度和容量大小
(7)vector预留空间
-
功能:
减少vector在动态扩容的次数 -
reserve函数:容器预留len个元素长度,(预留空间已开辟但未初始化,不可访问)
reserve(int len);
-
使用情景
在出入数据之前已知数据量的个数,可以使用预留空间,减少扩容次数,提高效率。 -
代码示例:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vc;
int *p = NULL;
int count = 0; //扩容次数
for(int i = 0; i < 2000; i++)
{
vc.push_back(i);
if(p != &vc[0])
{
p = &vc[0];
count++;
}
}
cout << count <<endl;
return 0;
}
结果:可见2000个数据的插入扩容了20次
- 使用vc.reserve()来优化吧
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vc;
vc.reserve(2000);
int* p = NULL;
int count = 0; //扩容次数
for (int i = 0; i < 2000; i++)
{
vc.push_back(i);
if (p != &vc[0])
{
p = &vc[0];
count++;
}
}
cout << count << endl;
return 0;
}
优化结果:
(三)下期内容
C++下一期:STL中vector容器的仿写