前言:
当我们学习过队列并学会了队列的简单操作,那么你是否想过:我不想按照元素的入队顺序进行输出,想让队列按照自己给它的规则出队?当你想到这的时候就代表你可以向下一步学习了--优先队列;
关于优先队列,最形象的比喻就是去医院看病了。每一个病人去看病都应该排队,和队列一样,按照先来先看病的顺序进行,但是在医院总是会碰到重病号,他们的时间很紧张,不可能按照排队的顺序来看病,这样就需要让他们优先就诊,因为他们的优先级高。在优先队列中就相当于每一次有新的元素进入队列时,队列中就会进行依次排序,按照优先级从大到小进行排序,优先级相同的元素就按照先来后到的顺序进行排序,所以优先队列每一次出队的都是优先级高或者来的早的元素。
一.优先队列的概念
普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。
在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先出队删除。优先队列具有最高级先出 (first in, largest out)的行为特征。通常采用堆数据结构来实现。
二.优先队列的实现方法
例子:输入6个元素,每个元素包含入队的顺序和优先级(优先级的数字越大,优先级越高);
6
1 2
2 1
3 7
4 3
5 9
6 2
对应的优先队列的操作:
填充颜色代表在优先队列中的位置进行了调整;
三.优先队列的申请和操作
A.申请优先队列
1.头文件
#include<queue>
using namespace std;
2.优先队列的申请
结构体类型: priority_queue<node>Q;
3.自定义的优先队列的排列准则
struct node
{
int x;//代表来的顺序;
int y;//代表优先级;
friend bool operator < (node a,node b)
{
if(a.y!=b.y)
return a.y<b.y;//先按照优先级由大到小进行排序;
else
return a.x>b.x;//如果优先级相同,就按照先后顺序排序;
}
};
4.优先队列的简单操作
a=Q.top(); Q为优先队列的名称,a为优先队列的队首元素;注意与队列的Q.front()进行区分;
Q.pop(); Q为优先队列的名称,队首元素出队列;
Q.size(); Q为优先队列的名称,判断优先队列现在所有的元素个数;
Q.empty(); Q为优先队列的名称,判断元素是否为空,0代表为非空,1代表为空;
5代码如下
#include<stdio.h>
#include<queue>
using namespace std;
struct node
{
int x;//代表来的顺序;
int y;//代表优先级;
friend bool operator < (node a,node b)
{
if(a.y!=b.y)
return a.y<b.y;//先按照优先级由大到小进行排序;
else
return a.x>b.x;//如果优先级相同,就按照先后顺序排序;
}
};
int main()
{
int n;
priority_queue<node>Q;
while(~scanf("%d",&n))
{
node a;
for(int i=0; i<n; i++)
{
scanf("%d%d",&a.x,&a.y);
Q.push(a);
}
int l=Q.size();
printf("优先队列有 %d 个元素。\n",l);
while(!Q.empty())
{
a=Q.top();
Q.pop();
printf("%d %d\n",a.x,a.y);
}
}
return 0;
}
6.运行结果