1. 在C语言中,很多东西需要自己去实现,并且实现不好的话容易出错,有些复杂的操作写起来也是相当麻烦,因此,C++为我们提供了标准模板库(Standard TemplateLibrary),其中封装了许多实用的容器,所以我们不需要费力去实现他们的细节而可以直接调用函数来实现很多的功能,这也类似于Java中的各种容易,比如是集合List,HashMap这些容器,有了这些容器我们操作数据也变得方便
2. 下面介绍的是vector常见的用法
① vector实际上就是一个长度可以改变的数组,这为们对数据长度不太确定的情况来说是一个很好解决办法,我们不同担心开辟多长的数组长度,直接声明这个vector即可
类似于Java中的List集合,只是语言中表达的方法是有多差别的,但是功能确是类似的,我们可以使用vector以邻接表的方式来存储图,这样就可以对于无法使用邻接矩阵又害怕使用指针实现邻接表的读者是非常友好的
② 如果需要使用vector我们需要添加vector头文件,即#include<vector>,除此之外还需要在头文件下面加上using namespace std;这样在代码中我们就可以使用vector了
③ vector的定义
单独定义一个vector:vector <typename> name;
这个定义其实是定义了一维数组name[size],只是这个size是可以根据情况来具体变化的,比较节省空间,其中的typename可以是任何的基本类型,例如int,double,char,结构体等,也可以是STL标准容器,例如vector、set、queue等需要注意的是如果typename是一个STL容易的时候需要在定义的时候在>>符号之间加上空格,因为在C++11之前标准的编译器会将其视为移位操作导致错误,下面是一些简单的例子:
vector<int> name;
vector<double> name;
vector<char> name;
vector<node> name;
vectot<vector<int> > name;
也可以将其定义成一个vector数组:
vector<typename> arrayName[arraysize];
例如:
vector<int> vi[100];
这样arrayName[]中的每一个元素都是一个vector,初学者可以将二维vector数组当做是两个维都可以边长的二维数数组理解
④ vector容器内元素的访问:vector有两种访问的方式,一种是通过下标的的方式来进行访问,另外一种是通过迭代器的方式来进行访问
1)通过下标来进行访问
和访问普通的数组是一样的,对于定义一个vector<typename>vi的容器来说,直接访问vi[index]即可,如vi[0],vi[1],当然这里的下标是1到vi.size() - 1访问这个范围之外的下标会出错
2)通过迭代器来进行访问
迭代器可以理解为是一种指针的东西,其定义是vector<typename> :: iterator it;
这样it就是一个vector<typename> :: iterator型变量这样就可以得到了迭代器it,我们可以通过*it来访问vector里面的元素
下面是具体的程序:
#include<iostream>
#include<vector>
using namespace std;
int main(void){
vector<int> vi;
for(int i = 0; i < 5; ++i){
vi.push_back(i);
}
//vi.begin()表示取vi的首元素地址,而it指向这个地址
vector<int> ::iterator it = vi.begin();
for(int i = 0; i < 5; ++i){
cout << *(it + i) << " ";
}
return 0;
}
⑤ 之前的vi.begin()函数是取出vi的首地址元素,那么存在end函数,取出的是尾元素地址的下一个地址,end可以作为迭代器末尾的标志,不存储任何的元素,下面是具体的代码:
#include<iostream>
#include<vector>
using namespace std;
int main(void){
vector<int> vi;
for(int i = 0; i < 5; ++i){
vi.push_back(i);
}
//vi.end()表示取vi的尾元素地址的下一个地址
vector<int> ::iterator it = vi.begin();
for(it; it != vi.end(); it++){
cout << *it << " ";
}
return 0;
}
3. 需要指出的是STL容器中只有在vector和string中才可以使用vi.begin() + 3这种迭代器加上整数的写法
下面是vector常用函数的实例解析:
① push_back(x):就是在vector后面添加一个元素x,时间复杂度为O(1),代码如下:
#include<iostream>
#include<vector>
using namespace std;
int main(void){
vector<int> vi;
for(int i = 0; i <= 3; i++){
vi.push_back(i + 1);
}
for(int i = 0; i < vi.size(); i++){
cout << vi[i] << " ";
}
return 0;
}
② pop_back()
pop_back()函数可以用来删除vector的尾元素,时间复杂度为O(1),下面是具体的代码:
#include<iostream>
#include<vector>
using namespace std;
int main(void){
vector<int> vi;
for(int i = 0; i <= 3; i++){
vi.push_back(i + 1);
}
vi.pop_back();
for(int i = 0; i < vi.size(); i++){
cout << vi[i] << " ";
}
return 0;
}
③ size函数用来获取vector中元素的个数
④ clear()
用来清空vector中的所有元素,时间复杂度为O(N),其中N为vector中元素的个数,代码如下:
#include<iostream>
#include<vector>
using namespace std;
int main(void){
vector<int> vi;
for(int i = 0; i <= 3; i++){
vi.push_back(i + 1);
}
vi.clear();
cout << vi.size() << " ";
return 0;
}
⑤ insert函数
insert(it, x)用来向vector的任意迭代器it处插入一个元素x,时间复杂度为O(N)
#include<iostream>
#include<vector>
using namespace std;
int main(void){
vector<int> vi;
for(int i = 0; i <= 3; i++){
vi.push_back(i + 1);
}
//将-1插入到vi[2]的位置
vi.insert(vi.begin() + 2, -1);
for(int i = 0; i < vi.size(); i++){
cout << vi[i] << " ";
}
return 0;
}
⑥ erase函数
存在着两种用法:删除单个元素,删除一个区间内的所有元素,时间复杂度为O(N)
① 删除单个元素
erase(it)即删除迭代器为it处的元素,代码如下:
#include<iostream>
#include<vector>
using namespace std;
int main(void){
vector<int> vi;
for(int i = 5; i <= 9; i++){
vi.push_back(i);
}
//删除8这个元素
vi.erase(vi.begin() + 3);
for(int i = 0; i < vi.size(); i++){
cout << vi[i] << " ";
}
return 0;
}
② 删除一个区间内的所有元素
erase(first, last)即删除[first, last)内的所有元,代码如下:
#include<iostream>
#include<vector>
using namespace std;
int main(void){
vector<int> vi;
for(int i = 5; i <= 9; i++){
vi.push_back(i);
}
vi.erase(vi.begin() + 1, vi.begin() + 4);
for(int i = 0; i < vi.size(); i++){
cout << vi[i] << " ";
}
return 0;
}
4. vector的常见用途:
① 本身可以违数组来进行使用,而且在元素个数不确定的场合可以很好地节省空间
有些场合需要根据一些条件把部分数据输出到同一行,数据中间使用空格隔开,由于输出的数据的个数是不确定的,所以可以使用vector来存储所有输出所有需要输出的数据然后一次性输出
② 使用邻接表来存储图