优先级队列
队列:特殊的线性表,在表的前端front删除元素,在表的后端rear插入元素,先进先出
优先级队列是一种特殊的队列,每次从队列中取出的是具有最高优先权的元素
优先级队列中每个元素都有一个关键字key,元素之间的比较都是通过key来比较的。
优先队列包括最大优先队列和最小优先队列
优先级队列的实现
优先队列的实现中,我们可以选择堆数据结构,最大优先队列可以选用大堆,最小优先队列可以选用小堆来实现。
下面实现了一个最大优先队列,使用数组实现的大顶堆。
最大优先队列一般包括插入、返回最大值、删除三个操作
插入操作
首先把该元素放入所有元素的下一位置,即数组中的最后一个位置,然后执行“上浮”操作,将该元素上浮到数组中的对应位置。
即调整数组位置,使数组满足大顶堆的性质。
获取最大值
返回集合S中具有最大key的元素,即为集合中的第一个元素,下标为0的元素。
移除操作
首先,在队列非空情况下,移除的永远是优先级最高的元素,即集合中第一个元素,也就是下标为0的元素。
然后将集合中最后一个元素移到下标为0位置,在将下标为0的新元素执行“下沉”操作,
即调整数字位置,使数组重新满足大顶堆的性质。
完整实现代码
import java.util.Arrays;
/**
* 优先队列类(最大优先队列)
*/
public class PriorityHeap {
// ------------------------------ Instance Variables
private int[] arr;
private int size;
// ------------------------------ Constructors
/**
* 优先队列数组默认大小为64
*/
public PriorityHeap() {
this(64);
}
public PriorityHeap(int initSize) {
if (initSize <= 0) {
initSize = 64;
}
this.arr = new int[initSize];
this.size = 0;
}
// ------------------------------ Public methods
public int max() {
return this.arr[0];
}
public int maxAndRemove() {
int t = max();
this.arr[0] = this.arr[--size];
sink(0, this.arr[0]);
return t;
}
public void add(int data) {
resize(1);
this.arr[size++] = data;
pop(size - 1, data);
}
// ------------------------------ Private methods
/**
* key下沉方法
*/
private void sink(int i, int key) {
while (2 * i <= this.size - 1) {
int child = 2 * i;
if (child < this.size - 1 && this.arr[child] < this.arr[child + 1]) {
child++;
}
if (this.arr[i] >= this.arr[child]) {
break;
}
swap(i, child);
i = child;
}
}
/**
* key上浮方法
*/
private void pop(int i, int key) {
while (i > 0) {
int parent = i / 2;
if (this.arr[i] <= this.arr[parent]) {
break;
}
swap(i, parent);
i = parent;
}
}
/**
* 重新调整数组大小
*/
private void resize(int increaseSize) {
if ((this.size + increaseSize) > this.arr.length) {
int newSize = (this.size + increaseSize) > 2 * this.arr.length ? (this.size + increaseSize) : 2 * this.arr.length;
int[] t = this.arr;
// Arrays的copyOf()方法传回的数组是新的数组对象,改变传回数组中的元素值,不会影响原来的数组
// copyOf()的第二个自变量指定要建立的新数组长度,如果新数组的长度超过原数组的长度,则保留数组默认值
this.arr = Arrays.copyOf(t, newSize);
}
}
/**
* Swaps arr[a] with arr[b].
*/
private void swap(int a, int b) {
int t = this.arr[a];
this.arr[a] = this.arr[b];
this.arr[b] = t;
}
/**
* main to test
*/
public static void main(String[] args) {
PriorityHeap ph = new PriorityHeap();
ph.add(3);
ph.add(5);
ph.add(2);
System.out.println(ph.max()); // 5
ph.add(1);
ph.add(4);
System.out.println(ph.maxAndRemove()); // 5
ph.add(2);
System.out.println(ph.max()); // 4
}
}