在算法比赛中,想要使用数据结构来存放数据,虽然之前介绍了栈,队列,链表等,但是在比赛中的有限时间中,我们不可能自己动手通过基本的数组,链表来组合或包装来获得自己需要的数据结构,所以掌握C++标准库中已经封装好的数据结构就显然成为一种不得不做的事。其实在之前介绍队列和栈时,我的源代码中就已经使用了标准库中的stack和queue,那么今天就介绍下标准库中另外两个基本的数据结构---vertor和list
1.vector
其实vertor就是升级版的数组,升级在哪里呢?数组在声明时就已经确定了大小,例如int a[20]就规定了这个数组最多只能存放20个元素,而vector的长度则是不固定的,通过一些方法可以自动的分配插入和删除释放一些内存空间,避免浪费内存和内存不够用。vector的几个基本方法如下:
函数名 | 功能 | 复杂度 |
size() | 返回向量的元素数 | O(1) |
push_back(x) | 在向量末尾添加元素x | O(1) |
pop_back() | 删除向量的最后一个元素 | O(1) |
begin() | 返回指向向量开头的迭代器 | O(1) |
end() | 返回指向向量末尾(最后一个元素的后一个位置) | O(1) |
insert(p,x) | 在向量的位置p处插入元素x | O(n) |
erase(p) | 删除向量中位置p的元素 | O(n) |
clear() | 删除向量中所有元素 | O(n) |
上面只是介绍了算法比赛中常用的方法,想要深入的同学可以在C++在线API文档之vector学习更多的方法.
以下是《挑战》书中给出的Demo
#include<iostream>
#include<vector>
using namespace std;
void print(vector<double> V)
{
for(int i=0;i<V.size();i++)
{
cout<<V[i]<<" ";
}
cout<<endl;
}
int main()
{
vector<double> V;
V.push_back(0.1);
V.push_back(0.2);
V.push_back(0.3);
V[2]=0.4; //V[x]的形式只能用来修改向量中已有的元素,不能用来添加元素
//V[3]=0.7; //此时V中元素最大小标为2,想通过V[3]来添加元素,是不能成功的
print(V); //0.1 0.2 0.4
V.insert(V.begin()+2,0.8);
print(V); //0.1 0.2 0.8 0.4
V.erase(V.begin()+1); //0.1 0.8 0.4
print(V);
V.push_back(0.9); //0.1 0.8 0.4 0.9
print(V);
V.pop_back();
print(V); //0.1 0.8 0.4
return 0;
}
2.list
list是STL中又一个重要的数据结构,不多废话,下面是它的常用方法:
函数名 | 功能 | 复杂度 |
size() | 返回表的元素数 | O(1) |
begin() | 返回指向表开头的迭代器 | O(1) |
end() | 返回指向表末尾(最后一个元素的后一个位置) | O(1) |
push_front(x) | 在表的开头添加元素x | O(1) |
push_back(x) | 在表的末尾添加元素x | O(1) |
pop_front() | 删除位于表开头的元素 | O(1) |
pop_back() | 删除位于表末尾的元素 | O(1) |
insert(p,x) | 在表的位置p插入元素x | O(1) |
erase(p) | 删除表中位置p的元素 | O(1) |
clear() | 删除表中所有元素 | O(n) |
其实list有点像链表,所以其插入insert和删除erase的时间复杂度都是O(1)。要注意list不能像vector一样使用[]通过下标访问指定的元素,只能通过迭代器iterator来遍历再访问,以下是包含迭代器的list的一个Demo.
#include<iostream>
#include<list>
using namespace std;
void print(list<char> L)
{
int i=0;
for(list<char>::iterator it=L.begin();it!=L.end();it++)
{
if(i++) cout<<" ";
cout<<*it;
}
cout<<endl;
}
int main()
{
list<char> L;
L.push_front('b'); //[b]
L.push_back('c'); //[bc]
L.push_front('a'); //[abc]
print(L);
cout<<L.front()<<endl; //a
cout<<L.back()<<endl; //c
L.pop_front(); //[bc]
L.push_back('d'); //[bcd]
print(L);
cout<<L.front()<<endl; //b
cout<<L.back()<<endl; //d
return 0;
}
vetor和list就简单介绍到这,只是最基本的用法,但是我感觉这在算法比赛已经完全够用了~实在不够就再学呗
PS:大年初一,听着外面的鞭炮声撸代码,写博客的感觉也是挺爽的~在这里祝大家新年快乐~