C++ STL(五)容器_vector
vector(向量):一个能够存放任意类型的动态数组。它是一个类模板,可用于表示多种不同的数据类型
所需头文件:#include<vector>
vector与数组的区别:
数组长度是固定的,在定义时就确定了数组的长度,不能在定义后修改数组长度,更不能添加或删除数组中的元素
vector长度是非固定的,可以随时改变数组的长度,添加或删除vector中元的元素
构造函数:
1 vector<int> vA; //构造个空的vector 2 vector<int> vB(5); //定义有5个int元素的vector (vB={0,0,0,0,0}) 3 vector<int> vC(5,1);//定义有5个int元素的vector,每个元素的值为1 (vC={1,1,1,1,1}) 4 vector<int> vD(vC); //通过vC拷贝构造一个vD (VD={1,1,1,1,1}) 5 int nArray[] = {1,2,3}; 6 int nLeng = sizeof(nArray)/sizeof(int); 7 vector<int> vE(nArray, nArray+nLeng); //通过数组拷贝构造一个vE (vE={1,2,3}) 8 //使用迭代器构造 9 vector<int> vv; 10 vv.push_back(1); 11 vv.push_back(2); 12 vv.push_back(3); 13 vv.push_back(4); 14 vv.push_back(5); 15 vector<int> vIt(vv.begin(),vv.end()); //正向迭代器方式构造vector (vIt={1,2,3,4,5}) 16 vector<int> vRit(vv.rbegin(), vv.rend()); //反向迭代器方式构造vector (vRit={5,4,3,2,1}) 17 18 //注意: 19 //begin()与end()配套使用. 正向迭代器 20 //rbegin()与rend()配套使用. 反向迭代器 21 //begin()返回指向vector第一个元素的迭代器 end()返回指向vector最后一个元素+1位置的迭代器 22 //rbegin()返回指向vector最后一个元素的迭代器 rend()返回指向vector第一个元素-1位置的迭代器 23 24 return;
获取大小和容量:
empty() 返回vector是否为空
size() 返回vector大小
max_size() 返回vector所能存储的最大元素个数,这是由系统自动定义的值
capacity() 返回重新分配空间前所能容纳元素最大个数
resize() 重新设置size,如果变长,变长的元素部份使用默认值,变短就删除多余的元素.会自动修改size与capacity,此时size==capacity
reserve() 重新设置capacity,只会修改capacity,不会修改size
1 vector<int> v; 2 bool bEmpty = v.empty(); //bEmpty = true 是否为空 3 v.push_back(1); 4 v.push_back(2); 5 bEmpty = v.empty(); //bEmpty = false 6 int nLeng = v.size(); //nLeng = 2 容器大小 7 int nMaxSize = v.max_size(); //nMaxSize = 1073741823 所能存储的最大元素个数,这是由系统自动定义的值 8 int nCapacity = v.capacity(); //nCapacity = 2 重新分配空间前所能容纳元素最大个数 9 10 //resize重新设置size,如果变长,变长的元素部份使用默认值,变短就删除多余的元素. 11 //会自动修改size与capacity,此时size==capacity 12 v.resize(10); 13 nLeng = v.size(); //nLeng = 10 14 nCapacity = v.capacity();//nCapacity = 10 15 //reserve重新设置capacity,只会修改capacity,不会修改size 16 v.reserve(20); 17 nLeng = v.size(); //nLeng = 10 18 nCapacity = v.capacity(); //nCapacity = 20
注意:size永远<=capacity, 当插入元素时有可能会根据size进行重新配置存储器,修改size和capacity,此时相关的迭代器将会失效
1 //例: 2 vector<int> vv; 3 for (int i=0; i<20; i++) 4 { 5 vv.push_back(3); 6 nLeng = vv.size(); 7 nCapacity = vv.capacity(); 8 printf("size=%d, capacity=%d\r\n",nLeng, nCapacity); 9 } 10 11 //例: 12 vector<int> vvv; 13 vector<int>::iterator it = vvv.begin(); 14 for (int j=0; j<20; j++) 15 { 16 vvv.push_back(3); 17 } 18 //错误方法: 19 for (it; it!=vvv.end(); ++it) 20 { 21 printf("%d ",*it); 22 } 23 24 //正确方法: 25 it = vvv.begin();//重新获取下迭代器 26 for (it; it!=vvv.end(); ++it) 27 { 28 printf("%d ",*it); 29 }
赋值操作:
数组[]和at()方式赋值
1 //使用数组[]和at()方式赋值 2 vector<int> vA(2); 3 vA[0] = 10; //vA = {10,0} 4 vA.at(1) = 11; //vA = {10,11}
assign()方式赋值
1 //使用assign()方式赋值 2 vector<int> vC; 3 //void assign(size_type _Count, const _Ty& _Val) 4 vC.assign(2,6); //给vC赋值二个int型元素,元素值为6 (vC={6,6}) 5 //void assign(_Iter _First, _Iter _Last) 6 vector<int> vD; 7 vC.assign(vD.begin(),vD.end()); //使用迭代器方式把vD中所有元素赋值给vC (vC={}) 8 9 //使用swap()交换方式赋值 10 vector<int> vE(2,3); 11 vector<int> vF(4,4); 12 vE.swap(vF); //vE = {4,4,4,4} VF = {3,3} 13 14 return;
增加元素操作:
push_back() 往vector末尾插入一个元素
insert() 往vector任意位置插入一个元素,指定位置或者指定区间进行插入,第一个参数都是个迭代器。返回值是指向新元素的迭代器
1 vector<int> vA; 2 //使用push_back()方式 3 vA.push_back(1); //vA中push一个1 (vA={1}) 4 5 //使用insert()方式插入元素, 第一个参数都是迭代器,返回值是指向新元素的迭代器 6 vector<int>::iterator it; 7 //iterator insert(const_iterator _Where, const _Ty& _Val) 指定位置插入 8 it = vA.insert(vA.begin(),2); //往begin()之前插入一个int元素2 (vA={2,1}) 此时*it=2 9 //void insert(const_iterator _Where, size_type _Count, const _Ty& _Val) 指定位置插入 10 it = vA.insert(vA.end(),2,3);//往end()之前插入2个int元素3 (vA={2,1,3,3}) 此时*it=3 11 //void insert(const_iterator _Where, _Iter _First, _Iter _Last) 指定区间插入 12 vector<int> vB(3,6); 13 it = vA.insert(vA.end(),vB.begin(),vB.end()); //把vB中所有元素插入到vA的end()之前 (vA={2,1,3,3,6,6,6}) 14 //此时*it=6,指向最后一个元素值为6的元素位置 15 16 return;
删除元素操作:
pop_back() 从vector末尾删除一个元素
erase() 从vector任意位置删除一个元素,指定位置或者指定区间进行删除,第一个参数都是个迭代器。返回值是指向删除后的下一个元素的迭代器
clear() 清除vector中所有元素, size=0, 不会改变原有capacity值
1 vector<int> vA; 2 vA.push_back(1); 3 vA.push_back(2); 4 vA.push_back(3); 5 vA.push_back(4); 6 vA.push_back(5); 7 //使用pop_back()方式 8 vA.pop_back(); //pop掉最后一个元素 (vA={1,2,3,4}) 9 10 //使用erase()方式删除元素,第一个参数都是迭代器,返回值是指向删除后的下一个元素的迭代器 11 vector<int>::iterator it; 12 //iterator erase(const_iterator _Where) 指定位置删除 13 it = vA.erase(vA.begin()); //删除Where位置的元素 (vA={2,3,4}) 此时*it=2 14 //void _Reverse(pointer _First, pointer _Last) 指定区间删除 15 it = vA.erase(vA.begin(),vA.end()); //把begin()到end()之间的所有元素删除 (vA={}) 16 //此时vector中己经没有元素了,迭代器指向的下一个元素就是删除前的第一个元素 *it=2 17 18 //使用clear()方式清除所有元素,size变为0 19 vector<int> vB(5,5); 20 vB.clear(); //(vB={},size=0 capacity=5) 21 22 return;
注意:不论是增加还是删除元素,迭代器都会发生改变,后续操作需要重新获取迭代器. 除末尾以外,其它位置插入或删除元素,都需要移动相关元素位置,执行效率低
遍历元素操作:
数组方式、迭代器方式
1 vector<int> vv; 2 vv.push_back(1); 3 vv.push_back(2); 4 vv.push_back(3); 5 vv.push_back(4); 6 vv.push_back(5); 7 8 //使用数组方式正向遍历 9 for (size_t i = 0; i<vv.size(); ++i) 10 { 11 cout<<vv[i]<<" "; 12 } 13 cout<<endl; 14 //使用数组方式反向遍历 15 for (size_t i = vv.size()-1; (int)i>=0; --i) 16 { 17 cout<<vv[i]<<" "; 18 } 19 cout<<endl; 20 //使用正向迭代器方式遍历 21 vector<int>::iterator it; 22 it = vv.begin(); 23 for (it; it!=vv.end(); ++it) 24 { 25 cout<<*it<<" "; 26 } 27 cout<<endl; 28 //使用反向迭代器方式遍历 29 vector<int>::reverse_iterator rit; 30 rit = vv.rbegin(); 31 for (rit; rit!=vv.rend(); ++rit) 32 { 33 cout<<*rit<<" "; 34 } 35 36 return;
释放内存操作:
使用swap()交换二个对象,使vector离开其自身的作用域,从而强制释放vector所占的内存空间
vector中元素是非指针的数据类型
1 vector<int> v(10,1); 2 v.clear(); 3 int nSize = v.size(); //nSize=0 4 int nCapacity = v.capacity(); //nCapacity=10,此时并不能减少容量释放内存 5 //使用空的vector与v进行交换 6 vector<int>().swap(v); 7 nSize = v.size(); //nSize=0 8 nCapacity = v.capacity(); //nCapacity=0
vector中元素是指针的数据类型
1 //new三个int型数据,定义三个指针用来保存,并且修改指针下的内容 2 int* p1 = new int(); 3 *p1 = 1; 4 int* p2 = new int(); 5 *p2 = 2; 6 int* p3 = new int(); 7 *p3 = 3; 8 //定义个int*的vector 9 vector<int*> vv(3); 10 vv[0] = p1; 11 vv[1] = p2; 12 vv[2] = p3; 13 //遍历vector,把所有指针类型元素指向的内存空间进行delete 14 vector<int*>::iterator it = vv.begin(); 15 for (it; it!=vv.end(); ++it) 16 { 17 if(NULL != *it) 18 { 19 delete *it; 20 *it = NULL; 21 } 22 } 23 //使用空的vector与vv进行交换 24 vector<int*>().swap(vv); 25 26 27 //此时尝试访问指针下的内容,己经访问不到了,说明己经确定释放了内存空间 28 int nValue = *p1; 29 nValue = *p2; 30 nValue = *p3; 31 //vector的Size与Capacity全为0,说明vector占用的内存空间也己经成功释放 32 nSize = vv.size(); //nSize=0 33 nCapacity = vv.capacity();//nCapacity=0
小练习题:
定义一个int型vector,包含1,3,2,3,3,3,4,3,5,3
删除容器中所有等于3的元素,最后遍历输出剩余元素
1 //定义一个int型vector,包含1,3,2,3,3,3,4,3,5,3 2 //删除容器中所有等于3的元素,最后遍历输出剩余元素 3 4 int nArray[] = {1,3,2,3,3,3,4,3,5,3}; 5 vector<int> vA(nArray, nArray+10); 6 vector<int>::iterator it = vA.begin(); 7 8 while (it!=vA.end()) 9 { 10 if(*it == 3) 11 { 12 //删除当前迭代器指向的元素,然后接收返回指向下个元素的迭代器赋值给it,接着遍历 13 it = vA.erase(it); 14 }else 15 { 16 ++it; 17 } 18 } 19 20 for (it = vA.begin(); it!=vA.end(); ++it) 21 { 22 cout<<*it<<" "; 23 } 24 //输出: 1 2 4 5 25 26 return;