一、Vector
使用vector需要头文件:include <vector>
(一)内存分配方式
Vector的存储方式和操作方式与array十分相似,区别是array是静态数组,需要分配指定大小的空间。Vector则不需要用户担心溢出和越界的问题,vector的空间分配是动态。
(二)迭代器
Vector与数组一样,其在内存中是一个连续的线性空间,所以一个普通的指针就能满足使用中的需求,如:operator*, operator->, operator++, operator+=等。
1.Vector的数据结构
Vector是连续线性空间,begin指向这段空间中第一个元素的位置,end指向超出末端的第一个位置,这两个指针标识了连续线性空间中以使用的范围。end_of_storage则指向连续线性空间的末尾。
注意:容器的大小和容量的概念是不同的。容器的大小指已使用的存储空间的长度,而容量则表示已使用+未使用的空间长度。Size()的返回值为已使用的大小,capacity()的返回值为容量。
2.Vector的内存分配策略
以最小的代价连续存储元素。但是为了vector容器能快速的分配内存,实际分配的容量会比当前所需的空间多一些,vector预留的空间来存放新加入元素,这就避免每新加一个元素都会进行“找到更大的内存->复制数据->销毁旧空间”的步骤。
注意:使用迭代器时,如果vector发生了扩容且引起了空间的重新分配,则所有的迭代器都会失效。
3.Vector的使用
(1)声明及初始化
vector<int> a; //声明一个int型向量a
vector<int> a(10); //声明一个初始大小为10的向量
vector<int> a(10, 1); //声明一个初始大小为10且初始值都为1的向量
vector<int> b(a); //声明并用向量a初始化向量b
vector<int> b(a.begin(), a.begin()+3); //将a向量中从第0个到第2个(共3个)作为向量b的初始值
int n[] = {1, 2, 3, 4, 5};
vector<int> a(n, n+5); //将数组n的前5个元素作为向量a的初值
vector<int> a(&n[1], &n[4]); //将n[1] - n[4]范围内的元素作为向量a的初值
(2)添加元素
vector<int> a;
a.push_back(1); //在尾部加入一个数据
a.push_back(2);
a.pop_back(); //删除最后一个数据
a.insert(a.begin(), 0); //在a.begin()之前加入0
a.erase(a.begin()); //将a.begin()的元素删除
a.erase(a.begin() + 1, a.end()); //将第二个元素以后的元素均删除
(3)判断是否为空
vector<int> a;
if(a.empty()){
a.push_back(1);
}
(4)遍历
vector<int> a;
//像数组一样以下标访问
for(int i = 0; i < a.size(); i++){
cout << a[i];
}
//以迭代器访问
vector<int>::iterator it;
for(it=a.begin(); it!=a.end(); it++){
cout<<*it<<" " ;
}
(5)排序
#include <algorithm>
vector<int> a;
sort(a.begin(), a.end());
(6)实现二维数组
vector<vector<int>> a(10, vector<int>(5)); //创建一个10行5列的int型二维数组 相当于a[10][5];