一、优先队列是什么
普通队列就是一种先进先出的数据结构,元素在队尾追加,从队首出队。
而优先队列就是一种元素间有优先级的队列,访问元素时一般是有最高优先级的元素先出(first in, largest out),常见的有小顶堆、大顶堆等。
二、c++中优先队列使用方法
头文件:#include< queue >
定义: priority_queue< Type,Container,Functional >
Type是数据类型,Container是容器类型(Container必须是数组实现的容器,如vector,deque等,stl中默认为vector),Functional是比较的方式。
若只传入Type数据类型,则默认为大顶堆
例:
//1、升序队列:小顶堆
priority_queue<int,vector<int>,greater<int>> q;
//2、降序队列:大顶堆
priority_queue<int,vector<int>,less<int>> q;
也可简写为 priority_queue<int> q;
操作: 优先队列具有普通队列的所有特性,包括基本操作也大体相同,只是在队列的基础上加了一个内部的排序,本质上是一个堆实现的。
- 和普通队列操作基本相同
- push 插入队尾(并自动排序)
- top 访问队首元素
- empty 判断队列是否为空
- size 返回队列元素个数
- emplace 原地构造一个元素并插入队列
- pop 弹出队首元素
- swap 交换内容
三、代码实现
例1: 借助优先队列实现堆排序
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int main()
{
int temp;
priority_queue<int> a;
priority_queue<int, vector<int>, greater<int> > b;
for(int i = 0;i < 5;i++)
{
cin >> temp;
a.push(temp);
}
for(int i = 0;i < 5;i++)
{
cin >> temp;
b.push(temp);
}
while(!a.empty())
{
cout << a.top() << " ";
a.pop();
}
cout << endl;
while(!b.empty())
{
cout << b.top() << " ";
b.pop();
}
}
例2: pair作为元素的优先队列
pair的排序原则:先比较第一个元素,若第一个相等则比较第二个
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
int main()
{
priority_queue< pair<int,int> > q;
pair<int,int> a(1,2);
pair<int,int> b(1,3);
pair<int,int> c(2,4);
q.push(a);
q.push(b);
q.push(c);
while(!q.empty())
{
cout << "<" << q.top().first << "," << q.top().second << ">" << endl;
q.pop();
}
return 0;
}
对于pair不了解的可见此文章
例3: 结构体作为元素的优先队列
priority_queue的底层是return x < y,所以我们要重载"<"
在用优先队列存边的信息时,实现代码如下
#include<iostream>
#include<queue>
using namespace std;
const int N = 50,M = 2500;
struct edge //结构体存边的信息
{
int u,v,w; //u为起点,v为终点,w为权值
};
bool operator<(edge a,edge b) //重载运算符"<"
{
return a.w > b.w;
}
priority_queue<edge> es; //建立优先队列es
int n,m; //总共有n个顶点,m条边
int main()
{
int a,b,c;
cin >> n >> m;
for(int i = 0;i < m;i++)
{
cin >> a >> b >> c; //输入起点,终点和权值
es.push({a,b,c});
}
for(int i = 0;i < m;i++)
{
cout << es.top().u << " " << es.top().v << endl;
es.pop();
}
return 0;
}