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;
vector构造

获取大小和容量:

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}
数组[]和at()方式赋值

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;
assign()方式赋值

增加元素操作:

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;
push_back()和insert()

删除元素操作:

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;
pop_back()和erase以及clear()

注意:不论是增加还是删除元素,迭代器都会发生改变,后续操作需要重新获取迭代器. 除末尾以外,其它位置插入或删除元素,都需要移动相关元素位置,执行效率低

遍历元素操作:

数组方式、迭代器方式

 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中元素是非指针的数据类型

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
vector中元素是指针的数据类型

 

小练习题:

定义一个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;
小练习题
posted @ 2019-12-25 15:13  SmallOverFllow  阅读(451)  评论(0编辑  收藏  举报