概述
优先队列,顾名思义是一个具有优先级别的队列,它并不是按照传统队列先进先出的顺序取出元素,而是会先取出优先级最高的那个元素,哪怕这个优先级最高的元素是最后插入的。
这是一个在算法竞赛中经常使用到的工具,因为手写堆很费时间,所以优先队列经常被拿来当作堆使用。
c++ priority_queue
priority_queue是c++的一个STL,它的头文件#include <queue>, 它的操作方法如下:
push() 插入一个元素
pop() 删除队列第一个元素
size() 返回队列中元素个数
empty() 如果队列空则返回true
top() 返回队列中的第一个元素
基本数据类型
下面的代码展示如何定义基本数据类型的优先队列,可以看到默认是大根堆,如果想要小根堆,那么需要多加两个泛型参数。
priority_queue<int> bigHeap; //大根堆
priority_queue<int, vector<int>, greater<int> > littleHeap; //小根堆
bigHeap.push(1);
bigHeap.push(2);
littleHeap.push(1);
littleHeap.push(2);
cout << bigHeap.top() << " " << littleHeap.top() << endl;
自定义结构体
优先队列进行比较时,使用的运算符是 <,在定义运算符规则时只需要记住,如果return a < b那么就是大根堆,如果return a > b那么就是小根堆,正好是反过来的。
下面展示如何创建一个自定义结构体的优先队列:
#include <iostream>
#include <queue>
using namespace std;
struct Student
{
string name;
int age;
};
//优先队列比较使用的运算符是 <,所以只定义这个运算符
bool operator<(const Student s1, const Student s2)
{
// 如果下面这行是大于,那么就是基于age的小根堆,反之就是大根堆
return s1.age > s2.age;
}
int main()
{
//自定义数据类型
Student s1 = {
"张三", 88}, s2 = {
"李四", 8}, s3 = {
"王五", 66};
priority_queue<Student> s;
s.push(s1);
s.push(s2);
s.push(s3);
while(!s.empty())
{
cout << s.top().name << " " << s.top().age << endl;
s.pop();
}
}
java PriorityQueue
java是一切皆对象,无法创建基本数据类型的优先队列,只能创建类的优先队列。所以就不需要再区分基本数据类型和自定义类了,不管是Integer和Double这种类还是自定义的其他类,都要实现Comparator<T>接口去自定义对应的比较器,否则就只能按照java内部默认的比较方法进行排序。
java中PriorityQueue的方法和Queue差不多,常用的如下:
add()插入
peek()返回头元素
poll()返回头元素并删除
clear()清空
size()元素个数
下面是创建优先队列的实例:
package demo01;
import java.util.Comparator;
import java.util.PriorityQueue;
class Student{
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
// 比较器
class CMP implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
// o1 - o2是小根堆,o2 - o1就是大根堆
return o1.age - o2.age;
}
}
public class Main{
public static void main(String[] args) {
PriorityQueue<Student> pq= new PriorityQueue<>(new CMP());
pq.add(new Student("zhangsan", 88));
pq.add(new Student("wangwu", 7));
pq.add(new Student("lisi", 66));
while (pq.size() > 0) {
Student student = pq.poll();
System.out.println(student.name + " " + student.age);
}
}
}