一、向量的介绍
向量 vector 是一种对象实体, 能够容纳许多其他类型相同的元素, 因此又被称为容器。 与string相同, vector 同属于STL(Standard Template Library, 标准模板库)中的一种自定义的数据类型, 可以广义上认为是数组的增强版。
在使用它时, 需要包含头文件 vector, #include<vector>
vector 容器与数组相比其优点在于它能够根据需要随时自动调整自身的大小以便容下所要放入的元素。此外, vector 也提供了许多的方法来对自身进行操作。
二、vector的定义
单独定义一个vector:
vector<typename> name;
//这里的typename可以是任何基本类型,例如 int、double、char、结构体等,也可以是STL标准容器,例如vector、set、queue等。
eg:
vector<int> name;
vector<double> name;
vector<char> name;
vector<node> name; //node是结构体的类型
vector<vector<int> > name; // >>之间要加空格
定义 vector 数组:
vector<typename> Arrayname[arraySize];
这样 Arrayname[0] ~ Arrayname[arraySize -1] 中每一个都是一个 vector 容器。
eg:
vector<int> vi[100];
三、vector容器内元素的访问
(1)通过下标访问
和访问普通数组是一样,对 vector 容器 vi 来说,直接访问 vi[index] (如 vi[0]、vi[1)]即可。这里下标是从 0 到 vi.szie()-1 。
(2)通过迭代器访问
迭代器(iterator)可以理解为一种类似指针的东西,其定义是:
vector<typename>::iterator it;
eg:
vector<int>::iterator it;
vector<double>::iterator it;
//这样就得到了迭代器 it ,并且可以通过 *it 来访问 vector 里元素。
#include<stdio.h>
#include<vector>
using namespace std;
int main()
{
vector<int> vi;
for (int i = 1; i <= 5; i++)
{
vi.push_back(i);
}
//vi.begin()为取vi的首元素地址,而it指向这个地址。
vector<int>::iterator it = vi.begin();
for (int i = 0; i < vi.size(); i++)
{
printf("%d ", *(it + i));
}
return 0;
}
从这里可以看出 vi[i] 和 *(vi.begin()+i) 是等价的。
此外,迭代器还实现了两种自加操作:++it 和 it++(自减操作同理)。
四、vector常用函数实例解析
(1)push_back()
push_back(x) 就是在 vector 后面添加一个元素 x ,时间复杂度为 O(1)。
(2)pop_back()
pop_back(x) 用以删除 vector 的尾元素,时间复杂度为 O(1)。
(3)size()
size() 用来获得 vector 中元素的个数,时间复杂度为 O(1)。size()返回的是 unsigned 类型,不过一般来说用 %d 不会出很大问题,这一点对所有 STL 容器都是一样的。
(4)clear()
clear() 用来清空 vector 中的所有元素,时间复杂度为 O(N),其中 N 为 vector 中元素的个数。
(5)insert()
insert(it,x) 用来向 vector 的任意迭代器 it 处插入一个元素 x,时间复杂度为 O(N)。
(6)erase()
1. 删除单个元素。
erase(it) 即删除迭代器为 it 处的元素。
2. 删除一个区间内的所有元素。
erase(first,last) 即删除 [first,last) 内的所有元素。
eg:
#include<stdio.h>
#include<vector>
using namespace std;
int main()
{
vector<int> vi;
for (int i = 1; i <= 10; i++)
{
vi.push_back(i);
}
//vi.begin()为取vi的首元素地址,而it指向这个地址。
vector<int>::iterator it = vi.begin();
for (int i = 0; i < vi.size(); i++)
{
printf("%d ", *(it + i));
}
vi.pop_back();
//vector的迭代器不支持 ite<vi.end() 写法,因此循环条件只能用 ite!=vi.end().
for (vector<int>::iterator ite = vi.begin();ite!=vi.end();ite++)
{
printf("%d ", *(ite));
}
vi.clear();
printf("\nsize:%d \n",vi.size());
it = vi.begin();
for (int i = 1; i <= 10; i++)
{
vi.push_back(i);
}
vi.erase(vi.begin() + 2);
for (vector<int>::iterator ite = vi.begin(); ite != vi.end(); ite++)
{
printf("%d ", *(ite));
}
vi.erase(vi.begin(), vi.end());
printf("\nsize:%d \n", vi.size());
return 0;
}
五、vector的常见用途
(1)存储数据
- vector 本身可以作为数组使用,而且在一些元素个数不确定的场合可以很好地节省空间。
- 有些场合需要根据一些条件把部分数据输出在同一行,数据中间用空格隔开。由于输出数据的个数是不确定的,为了更方便地处理最后一个满足条件的数据后面不输出额外的空格。可以先用 vector 记录所有需要输出的数据,然后一次性输出。
(2)用邻接表存储图
使用 vector 实现邻接表可以让一些对指针不太熟悉的读者有一个比较方便地写法。