(一)優先級隊列定義
(二)方法實現
獲得最大元素方法
去掉最大元素方法
修改優先級方法
添加節點
(三)實現
/**
* 用堆實現一個優先級隊列
* 主要是添加、修改、刪除節點
* 節點具有唯一性
* @author HHF
* 2014年11月28日
*/
public class PriorityQueue {
public static int HEAPSIZE;
public static void main(String[] args) {
int[] array = Common.random(0,100,10);
HEAPSIZE = array.length;
build(array);//建一個極大堆
System.out.println("原始數據:");
Common.print(array);
//獲得最大值
System.out.println("優先級最高的節點:"+maximum(array));
//獲得並刪除最大值
System.out.println("將要被刪除的優先級最高的節點:"+extractMax(array));
System.out.println("刪除後的數據:");
Common.print(array);
//修改優先級
increaseKey(array, 5, 100);
System.out.println("修改後的數據:");
Common.print(array);
//添加節點
insert(array, 101);
System.out.println("插入後的數據:");
Common.print(array);
//刪除節點
System.out.println("刪除的數據:"+delete(array, 1));
System.out.println("刪除後的數據:");
Common.print(array);
}
/**
* 返回優先隊列中優先級最高的節點
* @param array
* @return
*/
public static int maximum(int[] array){
return array[0];
}
/**
* 去掉並返回優先級隊列中優先級最高的節點
* @param array
* @return
*/
public static int extractMax(int[] array){
if(HEAPSIZE < 1){
(new Exception("隊列內無元素 ")).printStackTrace();
return 0;
}
//獲得最優節點
int max = array[0];
//刪除最優節點
array[0] = array[--HEAPSIZE];
//整理堆
heapify(array, 0);
//返回最優節點值
return max;
}
/**
* 往優先隊列中插入節點
* 記得要去重
* @param array
* @param x
*/
public static void insert(int[] array, int x){
array[HEAPSIZE++] = x-1;//加一個元素
increaseKey(array, HEAPSIZE-1, x);
}
/**
* 將優先級爲x的節點優先級修改爲k
* @param array
* @param i被修改值下標
* @param k
*/
public static void increaseKey(int[] array, int i, int k){
if(HEAPSIZE <= i){
(new Exception("修改優先級節點下標有誤 ")).printStackTrace();
return;
}
if(k <= array[i]){
(new Exception("新節點的優先級被改低了 ")).printStackTrace();
return;
}
//優先級被修改了
array[i] = k;
//整理隊列
int parent = (i-1)/2; //父節點下標
while(parent>-1 && array[parent]<array[i]){//到了必要交換子父節點的時候了
Common.swap(array, parent, i);
i = parent;
parent = (i-1)/2;
}
}
/**
* 將下標爲i的節點刪除 並返回其值
* @param array
* @param i
*/
public static int delete(int[] array, int i){
if(HEAPSIZE <= i){
(new Exception("刪除節點下標有誤 ")).printStackTrace();
return 0;
}
//優先級被修改了
int result = array[i];
//整理隊列
array[i] = -1;
heapify(array, i);
HEAPSIZE--;
return result;
}
/**
* 將array變成一個極大堆
* @param array 堆
*/
public static void build(int[] array){
int size = array.length;
for(int i=size/2-1; i>=0; i--){
heapify(array, i);
}
}
/**
* 前提是i的左右孩子子樹均已經爲正常極大堆
* 將i調整爲正確位置
* @param array
* @param i 下標
*/
public static void heapify(int[] array, int i){
int left = 2*i+1;//左孩子下標
int right = left+1;//右孩子下標
int large = 0;
//選出left right 和 i 三個下標對應的最大值 記其下標爲large
if(left<HEAPSIZE && array[left] > array[i]){
large = left;
}else{
large = i;
}
if(right<HEAPSIZE && array[right] > array[large]){
large = right;
}
//準備發生交換 和 遞推下一輪
if(large != i){
Common.swap(array, large, i);
heapify(array, large);//此時的i所對應的值 已經 下移一層到了large
}
}
}
(ps:附件內附上工具類Common.zip)