优先队列的实现是基于最大/最小堆的,队列的特性是先入先出(FIFO)。
最大优先队列指的是不管入队顺序如何,队列中的最大元素先出列。
最小优先队列指的是不管入队顺序如何,队列中的最小元素先出列。
//以最大优先队列为例
public class PriorityQueue {
private int[] array;
private int size;
public PriorityQueue(int capacity) {
this.array = new int[capacity];
this.size = 0;
}
public static void main(String[] args) throws Exception {
//最大优先队列
PriorityQueue priorityQueue = new PriorityQueue(6);
priorityQueue.enQueue(5);
priorityQueue.enQueue(1);
priorityQueue.enQueue(2);
priorityQueue.enQueue(6);
priorityQueue.enQueue(9);
priorityQueue.enQueue(3);
System.out.print(priorityQueue.deQueue() + " ");
System.out.print(priorityQueue.deQueue() + " ");
System.out.print(priorityQueue.deQueue() + " ");
System.out.print(priorityQueue.deQueue() + " ");
System.out.print(priorityQueue.deQueue() + " ");
System.out.print(priorityQueue.deQueue() + " ");
}
public void enQueue(int element) {
if (size >= array.length) {
resize();
}
array[size++] = element;
//最大堆的插入操作
upAdjust();
}
//通过不断‘上升’的方式构造二叉堆
public void upAdjust() {
int childIndex = size - 1;
int parentIndex = (childIndex - 1) / 2;
int temp = array[childIndex];
while (childIndex > 0 && temp > array[parentIndex]) {
array[childIndex] = array[parentIndex];
childIndex = parentIndex;
parentIndex = (childIndex - 1) / 2;
}
array[childIndex] = temp;
}
public int deQueue() throws Exception {
if (size <= 0) {
throw new Exception("queue is empty");
}
int element = array[0];
array[0] = array[--size];
//最大堆的删除操作
downAdjust();
return element;
}
public void downAdjust() {
int parentIndex = 0;
int childIndex = 1;
int temp = array[parentIndex];
while (childIndex < size) {
if (childIndex + 1 < size && array[childIndex] < array[childIndex + 1]) {
childIndex++;
}
if (temp >= array[childIndex]) {
break;
}
array[parentIndex] = array[childIndex];
parentIndex = childIndex;
childIndex = 2 * parentIndex + 1;
}
array[parentIndex] = temp;
}
public void resize() {
int[] newArray = new int[array.length * 2];
System.arraycopy(array, 0, newArray, 0, array.length);
array = newArray;
}
}