分类
Level5

优先队列

普通的队列是一种先进先出的数据结构,元素在队列尾追加,在队列头删除。优先队列是个具有优先级的队列,用”堆”来实现的。
在优先队列中,任何时刻,队首元素一定是当前队列中优先级最高(优先值最大)的那一个(大根堆),也可以是最小的那一个(小根堆)。可以不断往优先队列中添加某个优先级的元素,也可以不断弹出优先级最高的那个元素,每次操作其会自动调整结构,始终保证队首元素的优先级最高。

一、优先队列的原理及使用
priority_queue: 在优先队列中,优先级高的元素先出队列,并不是先进先出。
priority_queue<1,2,3>模板声明带有三个参数:
1 数据类型,
2 保存数据的容器,
3 元素比较方式。
数据的容器必须是用数组实现的容器,比如 vector, deque,STL里面默认用的是vector。如果把后面两个参数缺省的话,优先队列就是大顶堆,队头元素最大。priority_queue 默认按照从小到大排列,top()函数返回的是最大值。 如果使用参数greater<>,则数据从大到小排列,那么top()函数返回最小值,队头元素最小。
注意:priority_queue<1,2,3> 如果使用了第3个参数,那第2个参数(用作保存数据的容器)就不能省。

priority_queue<int> pq;//默认是大顶堆,top()返回最大值
priority_queue<int, greater<> > pq;//写法错误,不能省第二个参数
priority_queue<int,vector<int>,greater<int> > pq;//top()返回最小值
//假设node是结构体:
priority_queue<node> pq;//如果数据类型是自定义类型,要重载小于号
priority_queue<node,vector<node>,greater<node> > pq;//要重载大于号

二、基本操作

优先队列在头文件#include<queue> 中,定义和常用操作如下。优先队列的时间复杂度为O(logn),n为队列中元素的个数,其存取都需要时间。

priority_queue<int> a;//声明一个整型优先队列,默认是大根/大顶堆
empty( )  //判断一个队列是否为空
pop( )   //删除队顶元素
push( )  //加入一个元素
size( )  //返回优先队列中拥有的元素个数
top( )   //返回优先队列的队顶元素

三、使用方法举例

#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
 
int main(){
    int aa[8]={1,2,4,3,8,6,11,14};
    priority_queue<int,vector<int>,greater<int> > pq;//小顶堆 
    for (int i = 0; i < 8; i++) {
	pq.push(aa[i]);    //向队列中加入元素
    }
    sort(aa+0, aa+8);  //aa排序
    for (int i = 0; i < 8; i++)
	cout << aa[i] << ' '; //输出1 2 3 4 6 8 11 14
    cout<<endl;
    for (int i = 0; i < 8; i++){  //输出1 2 3 4 6 8 11 14
	cout << pq.top() << ' ';  //获取队头元素
	pq.pop();  //出队
    }
    cout<<endl;
    
    priority_queue<int,vector<int>,less<int> > pq2;//大顶堆
    for (int i = 0; i < 8; i++) {
	pq2.push(aa[i]);    //向队列中加入元素
    } 
	
    for (int i = 0; i < 8; i++){ //输出14 11 8 6 4 3 2 1
	cout << pq2.top() << ' ';  //获取队头元素
	pq2.pop();  //出队
    }
    return 0;
}

在优先队列中使用自定义数据类型,需要重载运算符:

#include<iostream>
#include<queue>
using namespace std;
struct node{
    int v,w;
    bool operator<(const node &nd) const{//重载小于号
        return w<nd.w; 
    }
};
priority_queue<node> q;
int main(){
	q.push({21,2}); 
	q.push({11,3}); 
	q.push({5,7}); 
	q.push({6,1}); 
	while(q.size()){//按w值从大到小出队
		cout<<q.top().v<<","<<q.top().w<<endl;
		q.pop();
	}
    return 0;
}
#include<iostream>
#include<queue>
using namespace std;
struct node{
    int v,w;
    bool operator>(const node &nd) const{//重载大于号
        return w>nd.w; 
    }
};
priority_queue<node,vector<node>,greater<node> > q;
int main(){
	q.push({21,2}); 
	q.push({11,3}); 
	q.push({5,7}); 
	q.push({6,1}); 
	while(q.size()){//按w值从小到大出队 
		cout<<q.top().v<<","<<q.top().w<<endl;
		q.pop();
	}
    return 0;
}