#include<iostream>
#include<queue>
#include<vector>
using namespace std;
/*模板类定义
template<class T, class Container = std::vector<T>,
class Compare = std::less<typename Container::value_type> > class priority_queue;
*/
void queueOperation();//队列
void priority_queueOrdinaryOperation();//普通优先队列
void priority_queuePairOperation();//使用pair的优先队列
void priority_queueRedefineOperation();//自定义优先队列
int main(){
queueOperation();//队列
priority_queueOrdinaryOperation();//普通优先队列
priority_queuePairOperation();//使用pair的优先队列
priority_queueRedefineOperation();//自定义优先队列
}
void queueOperation(){
//队列是先进先出的线性表。
//队列定义
queue<int>q;//使用默认构造函数创建队列
queue<char>q2;
queue<string>q3;
//queue<node>q4;//使用结构体作为数据类型
queue<vector<int>>q5;//使用容器作为数据类型
queue<int> myqueue({10, 20, 30});//使用初始化列表创建队列
for(int i=0;i<5;i++){
q.push(i*10);//队列的插入通过 push 成员函数实现,它可以将一个元素添加到队列的末尾
}
while(!q.empty()){
cout<<q.front()<<endl;//通过 front 成员函数访问队列的第一个元素
cout<<q.back()<<endl;//back() 返回最后一个元素
q.pop();//通过 pop 成员函数pop() 删除第一个元素,将其从队列中移除,直到队列为空
}
//队列中元素的查找是比较困难的,由于队列只能迭代访问,不能直接使用索引访问,
//所以要查找一个元素需要将队列中的元素移动到一个临时队列中,
//清空队列中的元素
//method1:逐个取出,知道队列为空
//method2:使用swap清空
queue<int>().swap(q);
//method3:重新创建一个队列,将原先的队列覆盖
q=queue<int>();
}
void priority_queueOrdinaryOperation(){
//默认大根堆
priority_queue<int>pq1;//从大到小排序
//标准一般写法
//小根堆
priority_queue<int,vector<int>,greater<int> >pq2;//从小到大排序
//大根堆
priority_queue<int,vector<int>,less<int> >pq3;//从大到小排序
priority_queue<string,vector<string>,greater<string> >pq4;//字符串类型,按照首字母a,b,c...z排序
for(int i=0;i<5;i++){
pq1.push(i*10);//push 插入元素到队尾并排序
}
while(!pq1.empty()){
cout<<pq1.top()<<endl;//top 访问队头元素
pq1.pop();//pop 弹出队头元素
}
}
void priority_queuePairOperation(){
//_____________piar_________________
//标准写法
priority_queue<pair<int,string>,vector<pair<int,string> >,greater<pair<int,string> > >q1;
/*
该优先队列 q1 是按照 pair<int,string> 类型的元素的第一个元素(即 int 类型的值)从小到大排序的,
如果第一个元素相等,则按照第二个元素(即 string 类型的值)从小到大排序。
这是因为在创建该优先队列时,使用了 std::greater<pair<int,string>> 作为元素之间的比较规则。greater<pair<int,string>>
是一个函数对象,用于比较两个 pair<int,string> 类型的元素。在该比较规则下,
如果第一个元素的值相等,则比较第二个元素的值,如果第二个元素的值也相等,则两个元素相等。
因此,该优先队列按照第一个元素的值从小到大排序,如果第一个元素相等,
则按照第二个元素的值从小到大排序。如果需要按照第一个元素的值从大到小排序,
可以使用less<pair<int,string>> 作为元素之间的比较规则。
*/
//当然也可以简写,不过默认大顶堆
priority_queue<pair<int,int> >q2;
//测试样例1:
pair<int,string> a(1,"b");
pair<int,string> b(1,"a");
pair<int,string> c(2,"c");
q1.push(a);
q1.push(b);
q1.push(c);
cout<<"q1:"<<endl;
while(!q1.empty()){
cout<<q1.top().first<<" ";
cout<<q1.top().second<<endl;
q1.pop();
}
//测试样例2:
pair<int,int> A(1,1);
pair<int,int> B(1,2);
pair<int,int> C(2,0);
q2.push(A);
q2.push(B);
q2.push(C);
cout<<"q2:"<<endl;
while(!q2.empty()){
cout<<q2.top().first<<" ";
cout<<q2.top().second<<endl;
q2.pop();
}
}
//自定义优先队列
#include<cstring>
//__________方法1:在结构体里重载运算符________
typedef struct Node{
int sum,id;
friend bool operator<(Node a,Node b){
return a.sum>b.sum;//通过属性sum建立小顶堆
}
}Node;
/*
关于结构体重载运算符和优先队列定义的解释:
priority_queue<Node> q1是默认定义方式,我们知道默认的应该是大顶堆,堆排序构建大顶
堆时,应该是当前节点小于(左、右)孩子,才进行交换,所以默认的运算符是'<',所以在结构体
重载运算符时,应该是friend bool operator<(Node a,Node b)。
而我们想实现通过sum建立小顶堆,所以重载'<'时,把真正的比较对象置为'>','>'是构建小顶
堆,所以使用默认方式建立优先队列,本来要读'<',实际上读的是'>',就简化了书写。(笑,这种方
法太坏蛋了)
*/
void priority_queueRedefineOperation(){
priority_queue<Node> q1;
//_________________方法2:重写仿函数__________________
typedef struct Node2{
int id,sum;
}Node2;
struct cmp{
bool operator()(const Node2 a,const Node2 b){
return a.sum<b.sum;//通过sum构建大顶堆
}
};
priority_queue<Node2,vector<Node2>,cmp >q2;
//测试样例1
Node a,b,c;
a.id = 1;a.sum = 10;
b.id = 2;b.sum = 3;
c.id = 3;c.sum = 6;
q1.push(a);
q1.push(b);
q1.push(c);
cout<<"q1:"<<endl;
while(!q1.empty()){
Node temp = q1.top();
q1.pop();
cout<<"id:"<<temp.id<<" "<<"sum:"<<temp.sum<<endl;
}
//测试样例2:
Node2 A,B,C;
A.id = 1;A.sum = 3;
B.id = 2;B.sum = 20;
C.id = 3;C.sum = 1;
q2.push(A);
q2.push(B);
q2.push(C);
cout<<"q2:"<<endl;
while(!q2.empty()){
Node2 temp = q2.top();
q2.pop();
cout<<"id:"<<temp.id<<" "<<"sum"<<temp.sum<<endl;
}
}
c++STL容器:队列&优先队列
最新推荐文章于 2024-03-19 00:04:57 发布