几种常见的STL容器
1、堆栈(stack) 先进先出(FIFO)
头文件:#include < stack >
定义方式: stack < int > s; //一个名为s的整形堆栈
操作:
s.push(x1); //将x1入栈
s.pop(); //出栈,注意:本操作执行的内容是删除栈顶元素,并不对它进行访问
s.top(); //访问栈顶
s.empty(); //判断栈是否为空,当栈空时,返回true。
s.size(); //访问栈中的元素个数
2、队列(queue) 后进先出(LIFO)
头文件:#include < queue >
定义方式: queue < int > q; //一个名为q的整形队列
操作:
q.push(x2); //将x2入队,即将x2连接到队尾
q.pop(); //出队,注意:本操作执行的内容是删除队首元素,并不对它进行访问
q.front(); //访问队首
q.back(); //访问队尾
s.empty(); //判断队列是否为空,当为空时,返回true。
s.size(); //访问队列中的元素个数
优先队列(priority_queue) 入队时默认大元素在队首,小元素在队尾
同样包含在< queue >中
priority_queue 模板类有三个模板参数,第一个是元素类型,第二个容器类型,第三个是比较算子。其中后两个都可以省略,默认容器为vector,默认算子为less
定义方式
priority_queue< int > q1;//默认定义
priority_queue<int, vector< int >, less< int > > q3; // 定义大的先出队,即默认定义
priority_queue< pair<int, int> > q2; // 注意在两个尖括号之间一定要留空格。
priority_queue<int, vector, greater > q3; // 定义小的先出队
priority_queue 的基本操作与queue 相同。
如果不是整形优先队列,而是结构体优先队列的话,可以在结构体的定义中对结构体的元素进行排序,重载大于或者小于符号就行,有点类似于sort()中的cmp;
如图所示:先排x再排y,注意写法(图片来自bilibili)
3、map 映射 (< 键值(key),实值(value) >)
map的特性是,所有元素都会根据元素的键值自动被排序。map的所有元素都是pair,同时拥有实值(value)和键值(key)。pair的第一个元素会被视为键值,第二个元素会被视为实值。map不允许两个元素拥有相同的键值。
map从本质上来说是一个映射关系,即键值和实值之间的映射。有点类似于数组的 a[2]=3 其中2是key(键值),3是value(实值)。
头文件:#include< map >
定义方式: map < int , int > mp;//一个名为mp的map
当然还有一些其他的定义方法:
map<string , int >strMap; //小心时间复杂度爆炸(string比较长的时候)
map<int ,string >intMap;
map<sring, char>strMap; //同样小心时间复杂度爆炸(string比较长的时候
map< char ,string>charMap;
map<char ,int>charMap;
map<int ,char >intMap;
用法:如图所示
这里要注意一下map的遍历和输出,其中的first就是对应的键值,second就是对应的实值。
4、set 集合
特征:set中不可能同时存在两个相同的元素(集合的互异性)
头文件:#include< set >
定义方式:set < int > s; //一个名为s的整形集合
操作集:
例如:
s.insert(1); //给集合中插入一个元素1
if(s.find(1)!=s.end())//如果在集合中找到了元素1,输出YES,没找到输出NO
//当然还有另一种写法是:if(s.count(1))
//这样写是因为如果集合中存在1,那么必定只有一个(互异性),即条件为真
//这样写的时间复杂度比较低,但是不适合于multiset!!
{
cout<<“YES”<<endl;
}else
cout<<“NO”<<endl;
**注意一点:map和set的操作(插入、查找、删除……)时间复杂度是log(n)
**
同样需要注意的是:set中也是默认排序的(把小的排在前面,即升序排列),所以set在用结构体数据类型的时候一定要把结构体排好序!!和上面写的一样
如下所示:
#include<iostream>
#include<set>
using namespace std;
int main()
{
set <int> s;
s.insert(3);
s.insert(1);
s.insert(2);
s.insert(5);
s.insert(4);
/*注意一下怎么输出集合中的所有元素*/
set<int>::iterator iter=s.begin();
while(iter!=s.end())
{
cout<<*iter<<endl;
iter++;
}
return 0;
}
multiset ( 多重集合 )
和set最大的区别就是,它可以插入重复的元素,如果删除的话,相同的也一起删除了;如果查找的话,返回该元素的迭代器的位置,若有多个相同元素,则返回第一个元素的地址;
所以不建议用s.count()来对元素的存在性进行查找,因为如果有多个相同的元素,它的时间复杂度也是很大的。所以还是建议用find()写。其他操作和set一样。
同样的,multiset也是排序好的
#include<iostream>
#include<set>
using namespace std;
int main()
{
multiset <int> ms;
ms.insert(1);
ms.insert(1);
ms.insert(1);
ms.insert(3);
ms.insert(6);
ms.insert(2);
ms.insert(0);
set<int>::iterator iter=ms.begin();
while(iter!=ms.end())
{
cout<<*iter<<endl;
iter++;
}
return 0;
}
5、vector(向量) 动态数组
头文件:#include< vector >
定义方式:vector < int > v;
常用操作:
未完待续……