一. 什么是vector
vector为“变长数组”,即长度根据需要而自动改变的数组。
头文件:
#include <vector>using namespace std;
单独定义一个vector:vector<typename> name
,相当于一维数组 name[SIZE] ,其长度可以根据需要变化,比较节省空间。
和一维数组一样,这里的 typename 可以是任何基本类型,如 int, double, char, 结构体等,也可以是STL标准容器,如vector, set, queue等。
在C++11之前,如果 typename 是一个STL容器,定义时需要在 >> 符号之间加空格,否则编译器会将它视为移位操作,导致编译错误。
例子:
vector<int> name;vector<char> name;vector<node> name; //node为结构体类型vector<vector<int>> name; //二维数组,两个维都可以变长//二维数组,一维长度固定为100,另一维变长,name[0]~name[99]每一个都是一个vector容器vector<int> name[100];
二. vector的初始化
- 不带参数的构造函数初始化
//初始化一个size为0的空vectorvector<int> abc;
- 带参数的构造函数初始化
//初始化size,但每个元素值为默认值vector<int> abc(10); //初始化了10个默认值为0的元素//初始化size,并且设置初始值vector<int> cde(10,1); //初始化了10个值为1的元素
- 通过复制同类型的vector初始化
vector<int> a(5,1);//通过复制a初始化vector<int> b(a);
- 通过复制 [begin,end) 区间内另一个数组的元素到vector中来进行初始化
int a[5] = {1,2,3,4,5};//通过数组a的地址初始化,注意地址是 [0, 5)vector<int> b(a, a+5);
三. vector容器内元素的访问
-
通过下标访问
和访问普通数组一样,对一个定义为vector<typename> name
的vector容器来说,直接访问 name[index] 即可(如name[0], name[1])。这里的下标是从0到name.size() - 1,访问这个范围外的元素可能会运行出错。 -
通过迭代器访问
迭代器(iterator)可以理解为一种类似指针的东西,其定义为:vector<typename>::iterator it;
这里 it 就是一个vector<typename>::iterator
型的变量,可以通过*it
来访问vector中的元素。
在常用STL容器中,只有在vector和string中,才允许使用 name.begin() + 3 这种迭代器加上整数的写法。
//name.begin()为取name的首元素地址,it指向这个地址vector<int>::iterator it = name.begin();for(int i = 0; i < name.size(); i++){printf("%d ", *(it + i)); //输出name[i]}//循环条件使用it != name.end(),不支持it < name.end()写法for(vector<int>::iterator it = name.begin(); it != name.end(); it++){printf("%d ", *it);}
四. vector常用函数
1. 添加
- void push_back(const T& x):在vector尾部添加一个元素x
- iterator insert(iterator it, const T& x):向vector中迭代器 it 处的前方插入一个元素x
- iterator insert(iterator it, int n, const T& x):向vector中迭代器 it 处的前方插入 n 个相同的元素x
- iterator insert(iterator it, const_iterator first, const_iterator last):向vector中迭代器 it 处插入另一个相同类型vector的 [first,last) 间的数据
vector<int> name;name.push_back(1); //1vector<int>::iterator it = name.begin();name.insert(it, 2); //2 1name.insert(it, 2, 3); //3 3 2 1vector<int> a(2, 0);name.insert(it, a.begin(), a.begin() + 1); //0 0 3 3 2 1
2. 删除
- void pop_back():删除vector中最后一个元素
- void clear():清空vector中所有元素
- iterator erase(iterator it):删除vector中迭代器 it 指向的元素
- iterator erase(iterator first, iterator last):删除vector中 [first,last) 范围内的元素
//0 0 3 3 2 1name.pop_back(); //0 0 3 3 2vector<int>::iterator it = name.begin();name.erase(it); //0 3 3 2name.erase(it, it + 1); //3 2name.clear();
3. 遍历
- iterator begin():返回向量头指针,指向第一个元素
- iterator end():返回向量尾指针,指向向量最后一个元素的下一个位置
- reference at(int pos):返回 pos 位置元素的引用
- reference front():返回首元素的引用
- reference back():返回尾元素的引用
- reverse_iterator rbegin():反向迭代器,指向最后一个元素,即将vector反转后,返回第一个元素
- reverse_iterator rend():反向迭代器,指向第一个元素之前的位置,即将vector反转后,返回最后一个元素
4. 判断
- bool empty() const:判断向量是否为空,若为空,则向量中无元素
if(name.empty()) return false;
5. 大小
- int size() const:返回向量中元素的个数
int len = name.size();
6. 通过copy函数赋值
vector<int> a(5,1);int a1[5] = {2,2,2,2,2};vector<int> b(10);//将a中元素全部拷贝到b开始的位置中,注意拷贝的区间为a.begin() ~ a.end()的左闭右开的区间copy(a.begin(), a.end(), b.begin());//拷贝区间也可以是数组地址构成的区间copy(a1, a1+5, b.begin() + 5);
五. vector排序
1. 从小到大(升序)
sort排序默认升序,头文件:#include <algorithm>
int a[] = {8,6,2,9,3,5,4,1,7,10};vector<int> arr(a, a+5);sort(arr.begin(),arr.end()); //升序
2. 从大到小(降序)
- (1)
greater<int>()
sort默认排序从小到大,使用greater<int>()
int a[] = {8,6,2,9,3,5,4,1,7,10};vector<int> arr(a, a+5);sort(arr.begin(),arr.end(),greater<int>()); //降序
- (2)自定义函数 bool cmp(int x, int y);
bool cmp_max(int x,int y){return x > y;
}int main() {int a[] = {8,6,2,9,3,5,4,1,7,10};vector<int> arr(a, a+5);sort(arr.begin(), arr.end(), cmp_max); for(int i = 0; i < arr.size(); i++){printf("%d ", arr[i]);} return 0 ;}
- (3)使用sort排序后,再使用reverse() ,reverse()将元素倒置
sort(arr.begin(),arr.end()); //升序排列reverse(arr.begin(),arr.end()); //将数组倒置
- (4)使用反向迭代器 rbegin() 和 rend()
// sorts arr in "normal" ordersort(arr.begin(), arr.end());// sorts in reverse: puts smallest element at the end of arrsort(arr.rbegin(), arr.rend());
关于反向迭代器,详见这篇博客:c++ vector begin(),end(),rbegin(),rend()问题 (C++ primer (中文版第四版) 第273页)
3. 对结构体vector使用sort排序
当vector中的数据类型为自定义结构体类型时(元素大于等于2),想以其中某一个元素进行正序或逆序排序,则不能直接使用sort函数,通过自定义比较函数 cmp 实现排序。
#include <bits/stdc++.h>
using namespace std;struct Point2{int x;int y;
};
bool GreaterSort (Point2 a,Point2 b) { return (a.x > b.x); }
bool LessSort (Point2 a,Point2 b) { return (a.x < b.x); }
int main(){vector<Point2> aaa;Point2 temp;temp.x=1;temp.y=1;aaa.push_back(temp);temp.x=2;temp.y=2;aaa.push_back(temp); temp.x=3;temp.y=3;aaa.push_back(temp);//降序排列sort(aaa.begin(),aaa.end(), GreaterSort);cout<<"Greater Sort:"<<endl;for (int i =0;i<aaa.size();i++){cout<<aaa[i].x<<" "<<aaa[i].y<<endl;}//升序排列sort(aaa.begin(),aaa.end(),LessSort);cout<<"Less Sort:"<<endl;for (int i =0;i<aaa.size();i++){cout<<aaa[i].x<<" "<<aaa[i].y<<endl;}return 0;
}
运行结果:
Greater Sort:
3 3
2 2
1 1
Less Sort:
1 1
2 2
3 3