简介:
Vector数组的特点:
- vector数组是一个能存放任意数据类型(类,结构,普通变量类型等)的动态数组,在数据结构中就相当于顺序储存的线性表,寻找元素非常快,但是插入元素的时间却很大(list是一个双向链表,在同一个位置插入大量的数据时速度很快,但是查找的速度就会慢很多)
- 和普通数组一样可以通过下标索引来进行访问!
- 与其它动态序列容器相比(deques,lists and forward_lists), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起lists和forward_lists统一的迭代器和引用更好。
- vector动态数组可以通过数组名进行直接赋值!
vectorc; vector b; b = c; - 缺点:当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。(比普通的数组具有更高的时间复杂度和空间复杂度)。
Vector数组的相关操作的实现:
1.vector数组的声明以及初始化
vector数组是C++的库函数,在调用时必须包含头文件#include<vector>
,并且在标准命名空间内调用using namespace std;
下面介绍几种创建vector数组以及初始化的方法。
#include<vector>
using namespace std;
vector<int>arr;//声明一个数组
vector<int>arr{1,2,3,4};//声明数组的同时初始化数组,arr数组的内容为1,2,3,4
vector<int>arr(4,1)//数组arr内容为1,1,1,1
int vec[5]={1,2,3,4,5};
vector<int>arr(vec,vec+5);//用数组vec的元素来初始化arr,内容为1,2,3,4,5
vector<int>arr(&arr[1],&arr[4]);//将vec[1]~vec[4]的元素作为arr的初始值,特别注意的是不包括vec[4],末尾指针都是指向结束元素的下一个元素
出于疑问,对后两种方式做了验证,代码如下
int vec[5] = { 1,2,3,4,5 };
cout << vec << endl;
cout << vec + 5 << endl;
for (int j = 0; j < 5; j++)
{
cout << "第" << j + 1 << "个元素的地址是" << &vec[j] << endl;
}
vector<int>arr(&vec[1], &vec[4]);
//cout << arr.size() << endl;
for (int i = 0; i < arr.size(); i++)
{
cout << arr[i]<<" ";
}
cout << endl;
vector<int>arr1(vec, vec + 5);
for (int m = 0; m < arr1.size(); m++)
{
cout << arr1[m] << " ";
}
运行结果如下图:
由此可知vec代表的是第一个元素的地址,而vec+5则是末尾元素的下一个地址(int类型为4个字节,第五个元素的地址加4即为后一位地址,刚好与vec+5吻合),由此可知在初始化vector数组时,小括号内的地址为前闭后开。
2.插入元素
插入元素操作有三个接口函数
①push_back();作用是在vector末尾插入新元素
②insert();第一个参数为迭代器,作用是在迭代器前面插入新的元素
③assign(3,2);向vector中加入3个2,同时清楚之前数组里的元素
测试代码如下:
vector<int>vec;
for (int i = 0; i < 10; i++)
{
vec.push_back(i);
}
for (int i = 0; i < vec.size(); i++)
{
cout << vec[i] << " ";
}
cout << endl;
vector<int>::iterator it;//创建迭代器
vector<int>vec2(vec);//将vec赋值给vec2
it = vec2.begin();
vec2.insert(it,1);
for (it = vec2.begin(); it != vec2.end(); it++)
{
cout << *it << " ";
}
cout << endl;
it = vec2.begin();//每当新插入一个元素时内存重新分配所以要重新为迭代器分配指针
vec2.insert(it, 2, 3);//在第一个元素前插入两个3
for (it = vec2.begin(); it != vec2.end(); it++)
{
cout << *it << " ";
}
cout << endl;
vector<int>vec3(vec2);
vec3.assign(3, 6);
for (int m = 0; m < vec3.size(); m++)
{
cout << vec3[m] << " ";
}
cout << "\n";
运行结果如下图:
3.删除操作
删除操作有四个元素接口:
①pop_back()删除最后一个元素
②erase()删除指定位置元素。(其中的参数为指针变量,例如begin(),end(),以及迭代器值)比如:vec.erase(vec.begin()+1);删除第二个元素
③clear()删除所有元素。
empty()判断数组是否为空
测试代码如下:
vector<int>vec{ 1,2,3,4,5 };
for (int i = 0; i < vec.size(); i++)
cout << vec[i] << " ";
cout << endl;
vec.pop_back();
for (int j = 0; j < vec.size(); j++)
cout << vec[j] << " ";
cout << endl;
vector<int>::iterator it;
it = vec.begin();
vec.erase(it + 1);//删除第二个元素
for (int m = 0; m < vec.size(); m++)
cout << vec[m]<<" ";
cout << endl;
vec.erase(vec.end()-1);//删除最后一个元素,因为vec.end()指针指向最后一个元素的下一个元素,因此指向末尾元素的指针应该为vec.end()-1
for (int n = 0; n < vec.size(); n++)
cout << vec[n]<<" ";
cout << endl;
vec.clear();
if (vec.empty())
cout << "数组为空" << endl;
运行结果如下:
4.遍历数组
可能用到的函数接口:
①front();访问第一个元素(第一个元素的值而不是地址,begin()相反)
②back();访问最后一个元素(最后一个元素的值而不是地址,end()相反)
③size();数组的元素个数
④创建迭代器
vector<int>vec;
vector<int>::iterator it;
it=vec.begin();
遍历数组一般有两种方式,一种是和数组一样使用下标遍历,另一种是使用迭代器访问,测试代码如下:
vector<int>vec{ 1,2,3,4,5 };
cout << "第一个元素的值为:" << vec.front() << endl;
cout << "第一个元素的地址为:" << &vec.begin() << endl;
cout << "最后一个元素的值为:" << vec.back() << endl;
cout << "最后一个元素的地址为:" << &vec.end() << endl;
//通过下标访问遍历
for (int i = 0; i < vec.size(); i++)
cout << vec[i] << " ";
cout << endl;
//通过迭代器访问
vector<int>::iterator it;
it = vec.begin();
for (it; it != vec.end(); it++)
cout << *it << " ";
cout << endl;
运行结果如下:
5.数组的翻转和排序
这里要用到reverse和sort函数,需要包含头文件#include<algorithm>
①reverse(vec.begin(),vec.end())函数实现数组元素的翻转,就是逆序排列
②sort(vec.begin(),vec.end())默认是从从小到大排列,同时结合翻转函数就能实现从大到小排列测试代码如下:
vector<int>vec{ 2,1,5,4,3,7,6 };
cout << "原数组为: ";
for (int i = 0; i < vec.size(); i++)
cout << vec[i] << " ";
cout << endl;
reverse(vec.begin(), vec.end());
cout << "翻转后的数组为: ";
for (int i = 0; i < vec.size(); i++)
cout << vec[i] << " ";
cout << endl;
sort(vec.begin(), vec.end());
cout << "从小到大排序:";
for (int i = 0; i < vec.size(); i++)
cout << vec[i] << " ";
cout << endl;
reverse(vec.begin(),vec.end());
cout << "从大到小排列:";
for (int i = 0; i < vec.size(); i++)
cout << vec[i] << " ";
cout << endl;
运行结果如下:
当然,对于排序还有很多其他的方法,快速排序,堆排序等等,这里只是演示以下可以直接调用的函数接口。
6.二维数组相关操作
二维数组的声明,初始化,遍历等操作由以下代码展示
#include<iostream>
#include<vector>
using namespace std;
#define count 3
//遍历二维数组
void traversal(vector<vector<int>>vec)
{
int i, j;
cout << "二维数组元素为: " << endl;
for (i = 0; i < vec.size(); i++)
{
for (j = 0; j < vec[0].size(); j++)
cout << vec[i][j] << " ";
cout << endl;
}
}
int main()
{
vector<vector<int>>vec(count);
for (int i = 0; i < vec.size(); i++)//初始一个3*3的二维数组
{
for (int j = 0; j < count; j++)
vec[i].push_back(6);
}
traversal(vec);
vector<vector<int>>vec2{ {1,2,3,4},{2,1,4,3} };//初始化一个2*4的二维数组
traversal(vec2);
cout << "2行4列的元素为:" << vec2[1][3] << endl;
cout << "vec2数组的行数为:" << vec2.size() << endl;
cout << "vec2数组的列数为:" << vec2[0].size() << endl;
vector<int>temp;
vec2.push_back(temp);//增加一行
int pos = vec2.size() - 1;
for (int i = 0; i < vec2[0].size(); i++)
vec2[pos].push_back(i);
cout << "增加一行后的";
traversal(vec2);
//增加一列
int pos2 = vec2.size();
for (int i = 0; i < pos2; ++i)
vec2[i].push_back(i);
cout << "增加一列后的";
traversal(vec2);
return 0;
}
运行结果如下图: