该优先队列的实现依赖于最大堆。关于最大堆,之前的博文:堆排序有讲。
- heapMaximum返回堆中键最大的元素,即array[0]。
- heapExtractMax方法删除并返回最大堆中最大键元素。
- heapIncreaseKey的作用是将元素i的关键字值增加到key
- maxHeapInsert方法是将元素插入到最大堆中
/**
* desc : 优先队列
* Created by tiantian on 2018/7/29
*/
public class PriorityQueue {
public static int heapSize = 0;
// 返回集合中最大键元素
public Integer heapMaximum(Integer[] array) {
return array[0];
}
// 去掉并返回集合中最大键元素
public Integer heapExtractMax(Integer[] array) throws Exception {
heapSize = array.length;
if (heapSize < 1) {
throw new Exception("heap underflow");
}
Integer max = array[0];
array[0] = array[--heapSize];
MaxHeap.heapMaxHeapfy(array, 0);
return max;
}
// 将元素i的关键字值增加到key
public void heapIncreaseKey(Integer[] array, int i, Integer key) throws Exception {
if (i > key) {
throw new Exception("key is smaller than current key");
}
array[i] = key;
int parent = MaxHeap.HeapNode.parent(i);
while (i > 0 && array[parent] < array[i]) {
MaxHeap.exchange(array, i, parent);
i = parent;
parent = MaxHeap.HeapNode.parent(parent);
}
}
// 将元素插入到最大堆中
public Integer[] maxHeapInsert(Integer[] array, Integer key) throws Exception {
heapSize = array.length + 1;
Integer[] newArray = new Integer[heapSize];
System.arraycopy(array, 0, newArray, 0, heapSize-1);
// 构造堆中最后一个元素为最小元素
newArray[heapSize-1] = -65535;
// 将最小元素增加到key即完成插入操作
heapIncreaseKey(newArray, heapSize-1, key);
return newArray;
}
}
优先队列所依赖的最大堆数据结构的实现如下
/**
* desc : 最大堆
* Created by tiantian on 2018/7/29
*/
public class MaxHeap {
public static int heapSize = 0;
// 维护最大堆
public static void heapMaxHeapfy(Integer[] array, int i) {
heapSize = array.length;
int l = HeapNode.left(i);
if (l >= heapSize) {
return;
}
int r = HeapNode.right(i);
if (r >= heapSize) {
return;
}
int largest;
if (l <= heapSize && array[l] > array[i]) {
largest = l;
} else {
largest = i;
}
if (r <= heapSize && array[r] > array[largest]) {
largest = r;
}
if (largest != i) {
exchange(array, i, largest);
heapMaxHeapfy(array, largest);
}
}
// 构建最大堆
public static void heapBuiltMaxHeap(Integer[] array) {
int i = (array.length)/2;
while (i >= 0) {
heapMaxHeapfy(array, i);
i--;
}
}
public static void exchange(Integer[] array, int a, int b) {
Integer temp = array[a];
array[a] = array[b];
array[b] = temp;
}
// 返回堆元素父节点下标,或者左右子节点下标。
public static class HeapNode {
public static int parent(int i) {
if (i == 2) {
return 0;
}
return i/2;
}
public static int left(int i) {
return 2*i+1;
}
public static int right(int i) {
return 2 * i + 2;
}
}
}