vector容器
一、vector容器概念
- vector是将元素置于一个动态数组(或可变数组)中加以管理的容器,连续内存空间,大小会根据元素个数进行自动增长。
- vector可以随机存取元素(支持索引值直接存取, 用[]操作符或at()方法,这个等下会详讲)。
- vector容器是一个单口容器,vector尾部添加或移除元素非常快速。但是在中部或头部插入元素或移除元素比较费时。
二、vector动态增长基本原理
当插入新元素时,如果空间不足,那么vector会重新申请更大的一块内存空间,将原空间数据拷贝到新空间,释放旧空间的数据,再把新元素插入新申请空间。
三、vector常用API
1、vector构造函数
2、vector常用赋值操作
3、vector大小操作
注意:resize 若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
4、vector数据存取操作
5、vector插入和删除操作
6、巧用swap缩减空间
由于vector的内存占用空间只增不减,比如你首先分配了10,000个字节,然后erase掉后面9,999个,留下一个有效元素,但是内存占用仍为10,000个。所有内存空间是在vector析构时候才能被系统回收。empty()用来检测容器是否为空的,clear()可以清空所有元素。但是即使clear(),vector所占用的内存空间依然如故,无法保证内存的回收。
7、reserve预留空间
如果知道容器大概要存储的元素个数,那么可以用reserve预留空间。
总结:vector是个动态数组,当空间不足的时候插入新元素,vector会重新申请一块更大的内存空间,将旧空间数据拷贝到新空间,然后释放旧空间。vector是单口容器,所以在尾端插入和删除元素效率较高,在指定位置插入,势必会引起数据元素移动,效率较低。
四、案例
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <vector> using namespace std; void PrintVector(vector<int>& v) { for (vector<int>::iterator it = v.begin();it != v.end();it++) { cout << *it << " "; } cout << endl; } //初始化 void test01() { vector<int> v1;//默认构造 int arr[] = { 10,20,30,40 }; vector<int> v2(arr, arr + sizeof(arr) / sizeof(int)); vector<int> v3(v2.begin(), v2.end()); vector<int> v4(v3); PrintVector(v2);//10 20 30 40 PrintVector(v3);//10 20 30 40 PrintVector(v4);//10 20 30 40 } //常用赋值操作 void test02() { //构造函数 int arr[] = { 10,20,30,40 }; vector<int> v1(arr, arr + sizeof(arr) / sizeof(int)); //成员方法 vector<int> v2; v2.assign(v1.begin(), v1.end()); //重载=号运算符 vector<int> v3; v3 = v2; //构造函数 int arr1[] = { 100,200,300,400 }; vector<int> v4(arr1, arr1 + sizeof(arr1) / sizeof(int)); PrintVector(v1);//10 20 30 40 PrintVector(v2);//10 20 30 40 PrintVector(v3);//10 20 30 40 PrintVector(v4);//100 200 300 400 cout << "------------------" << endl; v4.swap(v1);//v4与v1交换,交换原理:只是把内部指向数据的指针进行了交换 PrintVector(v1);//100 200 300 400 PrintVector(v2);//10 20 30 40 PrintVector(v3);//10 20 30 40 PrintVector(v4);//10 20 30 40 } //大小操作 void test03() { int arr[] = { 10,20,30,40 }; vector<int> v1(arr, arr + sizeof(arr) / sizeof(int)); cout << "size:" << v1.size() << endl;//size:4 if (v1.empty()) { cout << "空!" << endl; } else { cout << "不空!" << endl;//不空 } PrintVector(v1);//10 20 30 40 v1.resize(2); PrintVector(v1);//10 20 v1.resize(4); PrintVector(v1);//10 20 0 0 v1.resize(6,1); PrintVector(v1);//10 20 0 0 1 1 for (int i = 0;i < 100;i++) { v1.push_back(i); } //容量capacity>=元素的个数size cout << "元素的个数size:" << v1.size() << endl;//元素的个数size:106 cout << "容量capacity:" << v1.capacity() << endl;//容量capacity:141 } //vector存取数据 void test04() { int arr1[] = { 100,200,300,400 }; vector<int> v4(arr1, arr1 + sizeof(arr1) / sizeof(int)); //[]取值与at()取值的区别:索引值越界时,at抛异常,[]不抛异常 for (int i = 0;i < v4.size();i++) { //cout << v4[i] << " "; cout << v4.at(i) << " ";//100 200 300 400 } cout << endl; cout << "front:" << v4.front() << endl;//front:100 cout << "back:" << v4.back() << endl;//back : 400 } //vector插入和删除操作 void test05() { vector<int> v; v.push_back(10); v.push_back(20); //头插法 v.insert(v.begin(), 30); v.insert(v.end(), 40); v.insert(v.begin()+2, 100);//在这里可以用v.begin()+2,是因为:vector支持随机访问 //支持数组下标的,一般都支持随机访问 //迭代器可以直接 +某个数 或 -某个数 的操作 PrintVector(v);//30 10 100 20 40 //删除 v.erase(v.begin()); PrintVector(v);//10 100 20 40 v.erase(v.begin()+1,v.end()); PrintVector(v);//10 v.clear(); cout << "size:" << v.size() << endl;//size:0 } //巧用swap缩减空间 void test06() { //vector添加元素 它会自动增长,删除元素的时候,不会自动减少 vector<int> v; for (int i = 0;i < 10000;i++) { v.push_back(i); } cout << "size:" << v.size() << endl;//size:10000 cout << "capacity:" << v.capacity() << endl;//capacity:12138 v.resize(10); cout << "size:" << v.size() << endl;//size:10 cout << "capacity:" << v.capacity() << endl;//capacity:12138 //收缩空间: //swap技法就是通过交换函数swap(),使得vector离开其自身的作用域, //从而强制释放vector所占的内存空间。 //vector<int>(v):用v去初始化匿名对象,匿名对象会根据v的实际元素个数初始化它自己, //然后匿名对象的指针指向与v的指针指向交换,随后匿名对象自动释放 vector<int>(v).swap(v);//或者v.swap(vector<int>(v)); cout << "size:" << v.size() << endl;//size:10 cout << "capacity:" << v.capacity() << endl;//capacity:10 } void test07() { //reserve 预留空间 int num = 0;//统计自动增长的次数 int* address = NULL; vector<int> v; //如果知道容器大概要存储的元素个数,那么可以用reserve预留空间 v.reserve(10000); for (int i = 0;i < 10000;i++) { v.push_back(i); if (address != &(v[0]))//通过判断vector内存的首地址是否发生变化可知道是否申请了新的内存 { address = &(v[0]); num++; } } cout << "num:" << num << endl; } int main(void) { //test01(); //test02(); //test03(); //test04(); //test05(); //test06(); test07(); return 0; }