queue
常用优先队列
//升序队列,小顶堆
priority_queue <int,vector<int>,greater<int> > q;
//降序队列,大顶堆
priority_queue <int,vector<int>,less<int> >q;
(1)特点:
只能访问容器的第一个和最后一个元素
只能在容器的末尾添加新的元素
只能从头部移出元素
先进先出(FIFO,First in first out)
(2)定义:
queue<数据类型>名称;
queue<int>q1;
queue<char>q2;
(3)函数
back()返回最后一个元素
empty()如果队列为空返回true
front()返回队首元素
pop()删除队首元素
push()在末尾加入一个元素
size()返回队列中元素的个数
基本操作:
q1.push(1);//向q1这个队列中插入1这个数字
int len=q1.size();
int a=q1.fount();
pair
pair就是一个结构体,但是比结构体更加灵活,一般使用typedef优化,
pair<T1,T2>中T1和T2可以是不同的数据类型
(1)定义
pair<int,int>p1;
pair<int,double>p2(1,2.5); //定义的同时 还初始化了
pair<int double>p3(p2); //拷贝构造函数
(2)访问:通过first和second
p1.first=1;
p1.second=2;
cout<<p1.first<<" "<<p1.second<<endl;
(3)赋值用make_pair
pair<int,double>p4;
p4 = make_pair(1,2.38);
p5 = p4; //变量间赋值
(4)应用:
如果一个函数有两个返回值 的话,如果是相同类型,就可以用数组返回,如果是不同类型,就可以自己写个
struct ,但为了方便就可以使用 c++ 自带的pair ,返回一个pair,其中带有两个值。除了返回值的应用,在一个对象
有多个属性的时候 ,一般自己写一个struct ,如果就是两个属性的话,就可以用pair 进行操作
set集合
(1)特点:
set中元素是排好序的,从小到大(默认升序排列)
set中没有重复元素
(2)定义:
//set<数据类型>名称;
set
(3)常用函数:
s.begin(); //返回指向容器 最开始位置 数据的 ==指针==
s.end(); //返回指向容器最后一个数据单元 ==+1的指针==
s.insert(); //插入
s.clear(); //清空
s.empty(); //判断set是否为空
s.size(); //返回set中元素的个数
s.erase(); //删除迭代器指针it处元素
s.count(x) //返回x出现的次数(因为是集合 只可能是0或1)
注意:插入规则在默认的比较规则下,是按元素值从小到大插入,如果自己指定了比较规则函数,则按自定义比较规则函数插入。
set<int>::iterator it; //定义前向迭代器
set<int>::reverse_iterator rit; //定义反向迭代器
看这两个代码:
#include<iostream>
#include<set>
using namespace std;
int main()
{
set<int> s;
s.insert(5); //第一次插入5,可以插入
s.insert(1);
s.insert(6);
s.insert(3);
s.insert(5); //第二次插入5,重复元素,不会插入
set<int>::iterator it; //定义前向迭代器
//中序遍历集合中的所有元素
for(it = s.begin(); it != s.end(); it++)
{
cout << *it << " ";
}
//cout <<s.end()<< endl;报错
cout << endl;
return 0;
}
//运行结果:1 3 5 6
第二个代码:
(元素的方向遍历
使用反向迭代器reverse_iterator可以反向遍历集合,输出的结果正好是集合元素的反向排序结果。
它需要用到 rbegin()和rend() 两个方法,
它们分别给出了反向遍历的开始位置和结束位置。)
#include<iostream>
#include<set>
using namespace std;
int main()
{
set<int> s;
s.insert(5); //第一次插入5,可以插入
s.insert(1);
s.insert(6);
s.insert(3);
s.insert(5); //第二次插入5,重复元素,不会插入
set<int>::reverse_iterator rit; //定义反向迭代器
//反向遍历集合中的所有元素
for(rit = s.rbegin(); rit != s.rend(); rit++)
{
cout << *rit << " ";
}
cout << endl;
return 0;
}
//运行结果:6 5 3 1
(4)元素的删除s.erase(键值);
(5)元素的检索
使用find()方法对集合进行检索,如果找到查找的的键值,则返回该键值的 迭代器位置 ;否则,返回集合最后一个元素后面的一个位置,即end()
(6)自定义比较函数
使用insert将元素插入到集合中去的时候,集合会根据设定的比较函数奖该元素放到该放的节点上去。在定义集合的时候,如果没有指定比较函数,那么采用 默认的比较函数,是按键值从小到大的顺序插入元素。但在很多情况下,需要自己编写比较函数。
编写比较函数有两种方法。
(1)如果元素不是结构体,那么可以编写比较函数。下面的程序比较规则为 按键值从大到小的顺序插入到集合中 。
#include<iostream>
#include<set>
using namespace std;
struct mycomp
{
//自定义比较函数,重载“()”操作符
bool operator() (const int &a, const int &b)
{
if(a != b)
return a > b;
else
return a > b;
}
};
int main()
{
set<int, mycomp> s; //采用比较函数mycomp
s.insert(5); //第一次插入5,可以插入
s.insert(1);
s.insert(6);
s.insert(3);
s.insert(5); //第二次插入5,重复元素,不会插入
set<int,mycomp>::iterator it;
for(it = s.begin(); it != s.end(); it++)
cout << *it << " ";
cout << endl;
return 0;
}
/*
运行结果:6 5 3 1
*/
(2)如果元素是结构体,那么可以直接把比较函数写在结构体内
#include<iostream>
#include<set>
#include<string>
using namespace std;
struct Info
{
string name;
double score;
bool operator < (const Info &a) const // 重载“<”操作符,自定义排序规则
{
//按score由大到小排序。如果要由小到大排序,使用“>”即可。
return a.score < score;
}
};
int main()
{
set<Info> s;
Info info;
//插入三个元素
info.name = "Jack";
info.score = 80;
s.insert(info);
info.name = "Tom";
info.score = 99;
s.insert(info);
info.name = "Steaven";
info.score = 60;
s.insert(info);
set<Info>::iterator it;
for(it = s.begin(); it != s.end(); it++)
cout << (*it).name << " : " << (*it).score << endl;
return 0;
}
/*
运行结果:
Tom : 99
Jack : 80
Steaven : 60
*/
stack栈
(1)特点:
只能访问栈顶元素,
插入删除只能在栈顶操作
插入叫入栈,删除叫出栈
后进先出
(2)定义
stack<int> s; //stack<数据类型> 名称;
stack<double> s;
(3)函数
s.empty() //判断栈是否为空
s.size() //返回栈中元素个数
s.pop() //删除栈顶元素
s.top() //返回栈顶元素但不删除该元素
s.push(x) //在栈顶压入新元素