简介:
Vector数组的特点:

  1. vector数组是一个能存放任意数据类型(类,结构,普通变量类型等)的动态数组,在数据结构中就相当于顺序储存的线性表,寻找元素非常快,但是插入元素的时间却很大(list是一个双向链表,在同一个位置插入大量的数据时速度很快,但是查找的速度就会慢很多)
  2. 和普通数组一样可以通过下标索引来进行访问!
  3. 与其它动态序列容器相比(deques,lists and forward_lists), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起lists和forward_lists统一的迭代器和引用更好。
  4. vector动态数组可以通过数组名进行直接赋值!
    vectorc; vector b; b = c;
  5. 缺点:当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,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;
}

运行结果如下图:
在这里插入图片描述

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐