c++-----STL容器系列(1) vector
1 介绍
Vector是stl容器中一种常见的容器 ,基本和数组类似,其大小(size)可变,常用于数组长度不确定时来代替数组,当数据超过vector预定值时vector将自动扩容。
Vector是一种顺序存储器,在内存中连续排列,可以通过下标访问,时间复杂度为O(1)。
2 创建和使用
使用时需要包含头文件
1 #include<vector>
声明一个int型的vector数组
1 Vector<int> asd; 一个空数组 2 Vector<int> asd1 {1,2,3,4,5}; 包含1、2、3、4、5个变量 3 Vector<int> asd2(9); 开辟9个空间,且默认值为0 4 Vector<int> asd3(3,5); 3个值为5的数组 5 Vector<int> asd4(asd3); 复制asd3的所有值 6 Vector<int> asd5(asd4.begin(),asd4.end()); 将asd4的值从头到尾复制 7 Vector<int> asd6(asd4.rbegin(),asd4.rend()); 将asd4的值从未到头复制
方法
名字 |
描述 |
begin |
返回指定容器中第一个元素的迭代器 |
end |
返回指定容器最后一个元素所在位置后一个位置的迭代器 |
Size |
返回实际元素的个数 |
Max_size |
返回元素个数的最大值 |
empty |
判断vector是否为空 |
at |
Vector.at(i)等同于vector[i],访问数组下标的元素 |
front |
返回第一个元素 |
back |
返回最后一个元素 |
Push_back |
在容器尾部插入元素 |
Pop_back |
删除最后一个元素 |
insert |
插入元素 |
erase |
删除元素 |
swap |
两元素交换 |
capacity |
可容纳的大小 |
3具体用法
3.1 遍历
1 //范围for循环 2 for(auto num :asd){ 3 Cout<num<<endl; 4 } 5 //下标访问 6 for(int i=0;i<asd.size();i++){ 7 Cout<<asd[i]<<endl; 8 } 9 //迭代器访问 10 for(vector<int>::iterator it=asd.begin();it!=asd.end();it++){ 11 cout<<*it<<endl; 12 }
3.2容量和大小
resize改变size的大小,而reserve改变capacity的大小
1 Vector<int> asd; 2 Asd.resize(4); 3 Asd.reserve(6); 4 Cout<<asd.size()<<””<<asd.capacity()<<endl;
3.3vector常用算法
3.3.1push_back和pop_back
1 Vector<int> asd; 2 For(int i=0;i<9;i++){ 3 Asd.push_back(i); 4 } 5 For(int i=0;i<9;i++){ 6 Asd.pop_back(); 7 }
3.3.2 erase
erase通过迭代器删除某个或者某个范围的元素,并返回下一个元素的迭代器
1 Vector<int> asd{1.、2、3、4、5、6}; 2 Asd.erase(asd.begin()+2); 3 //删除asd开头往后偏移两个位置的元素
3.3.3 swap和clear
1 vector<int> asd={5,4,3,2,1}; 2 Vector<int> asd1={1,2,3,4,5}; 3 Asd.swap(asd1); 4 //swap将两个vector进行交换 5 Asd.clear(); 6 //clear清空整个vector,size变为0
3.4 vector二维操作
定义一个二位的数组
1 Vector<vector<int>> asd;
定义一个5行三列且全为1的二维数组
1 Vector<vector<int>> asd(5,vector<int>(3,1));
访问
1 //For循环访问 2 For(int i=0;i<asd.size();i++){ 3 For(int j=0;j<asd[0].size();j++){ 4 Cout<<asd[i][j]<<endl; 5 } 6 } 7 For(auto nums :asd){ 8 For(auto num :nums){ 9 Cout<<num<<endl; 10 } 11 }
4 vector扩容原理
扩容原理概述
- 新增元素:vector通过一个连续的数组存放元素,如果集合已满,在新增数据的时候,就要分配一块更大的内存,将原来的数据复制过来,释放之前的内存,在插入新增的元素;
- 对vector的任何操作,一旦引起空间重新配置,指向原vector的所有迭代器都失效;
- 初始时刻vector的capacity为0,塞入第一个元素后capacity增加到1;
- 在不同编译器实现的扩容方式不一样,VS015中以1.5倍扩容,GCC以2倍扩容
以下是vs中vector的扩容源码
总结
- vector在push_back以成倍增长可以在均摊后达到O(1)的事件复杂度,相对于增长指定大小的O(n)时间复杂度更好。
- 为了防止申请内存的浪费,现在使用较多的有2倍与1.5倍的增长方式,而1.5倍的增长方式可以更好的实现对内存的重复利用。