vector容器
基本概念
功能:
vector数据结构和数组非常相似,也称为单端数组
与普通数组的区别
不同之处在与数组是静态空间,而vector可以动态扩展
动态扩展
并不是在原空间后面续新空间,而是找到更大的内存存储,再把原来的销毁
vector容器的几个迭代器
v.begin()指向第一个元素
v.end()指向最后一个元素的后一个位置
v.rend()指向第一个元素的前一个位置
v.rbegin()指向最后一个元素
vector构造函数
功能:创建vector容器
函数原型:
vector<T>v; 采用模板实现
vector(v.begin(),v.end()) 从第一个元素到最后一个元素,所以是 【v.begin(),v.end())
vector(n,elem) 用n个elem 构造容器
vector<int>v(const vector&vec) 拷贝构造函数,拷贝另一个vevtor容器
vector赋值操作
-
= 赋值
一个已经有数据的vector容器v1 vector<int>v2; v2=v1;
-
assign方式
一个已经有数据的vector容器v1
vector<int>v2;
v2.assign(v1.begin(),v1.end());
assign里面的迭代器范围依然是 左边闭区间,右边开区间
以上代码将v1的元素赋值给v2。
vector<int>v2;
v2.assign(10,100);
这个与string容器的assign一样,10个100。
vector容量和大小
empty() 判断容器是否为空,为空则返回true,不为空返回false
capacity() 容器的容量,
size() 返回容器中元素个数
resize(int num) 重新指定容器的长度为num,若原来的元素个数超过num,超出的部分被删除;若少于 num,不足的用0填充
resize(int num,elem) resize(int num)的重载版本,与之不同的是,填充时可指定填充的数据为elem。
vector插入与删除
const_iterator 代表迭代器类型
函数原型:
push_back(elem) 尾部插入值elem
pop_back() 删除最后一个值
insert(const_iterator pos,elem) 迭代器的位置插入值elem
insert(const_iterator pos,int cout,elem) 迭代器位置插入cout个数的elem
erase(const_iterator pos) 删除迭代器位置的元素
erase(const_iterator start,const_iterator end) 删除两个迭代器之间的元素
clear() 删除容器中全部元素
注:
删除操作可以这样用
v1.insert(v1.begin(),v1.begin()+2);
另外发现,在删除和清空的操作后,容器的容量是保持不变的。
vector容器数据存取补充
除了使用迭代器获取vector容器中的元素外,还有其它方法访问:
- 【】 可以用中括号访问
- at 类似于中括号的方式,如 v1.at(1)
- front返回容器第一个元素
- back返回容器最后一个元素
vector互换容器
函数原型 swap(const vector&vec)
作用:可以使两个容器互换,可以达到实用的收缩内存的作用。
收缩内存作用的示例:
vector<int>v;
for(int i=0;i<10000;i++)
{
v.push_back(i);
}
此时容器的大小为10000,容量比大小更是大出不少,如果此时指定容器大小:
v.resize(3);
此时容器的容量还是原来那样大,造成内存浪费,此时用巧用swap可以收缩内存:
vector<int>(v).swap(v);
容器拷贝构造的代码: vectorv2(const vector&v1)
上面这段代码vector(v) 是通过拷贝构造,构造了一个匿名对象,其实际容量和大小是按v容器重新指定大小后的样子来拷贝构造的,故此时它的容量是很小的;此时再调用swap,相当于把这个小容器换给了v,匿名对象在当前代码实现完后系统释放,此时便达到了收缩内存的作用。
当然,在没有重新指定容器大小的情况下,依然可以这样用:
vector<int>v1;
for (int i = 0;i < 10000;i++)
{
v1.push_back(i);
}
cout << v1.capacity() << endl;
vector<int>(v1).swap(v1);
cout << v1.capacity() << endl;
同样可以收缩内存。
vector预留空间
功能:
减少vector在动态扩展容量时的扩展次数
函数原型:
reserve(int len);//容器预留len个元素,预留位置如果不初始化,就不能访问。
看下面一段代码
vector<int>v1;
int num;
int*p;
for (int i = 0;i < 10000;i++)
{
v1.push_back(i);
if(p!=v[0])
{
p=v[0];
num++;
}
}
因为vector容器在开辟内存不够用时,会重新开辟内存,通过上面的代码可以看出其重新开辟了多少次。
如果我们提前知道需要多少内存,就可以预留空间,减少重新开辟的次数了。
v.reserve(10000);
总结:如果数据量较大,可以一开始利用reserve预留空间