本文章代码来自于项目:http://git.oschina.net/jiangkun/Introduction_to_Algorithms-Third_Edition-Answers
欢迎大家一起参与!我会不定时更新!
package acm;
/*
* 算法导论(第三版)第6章 堆排序的实现,优先队列的实现
* 具体原理参看书本。
*
* */
public class PriorityQueue {
private static int[] arr;
public PriorityQueue(int[] s)
{
arr = s.clone();
buildMaxHeap(arr);
}
public static void main(String[] args)
{
int[] s = {4,1,3,2,16,9,10,14,8,7};
//max_heapify(s, s.length, 1);
//buildMaxHeap(s);
PriorityQueue pq = new PriorityQueue(s); //得到最大堆
pq.printAll();
heapInsert(100); //添加一个值
pq.printAll();
int max = pq.heapExtractMax(); //删除最大值
System.out.println(max);
pq.printAll();
pq.heapIncreaseKey(9,20); //增加某位置处的值
pq.printAll();
pq.heapDecreaseKey(0, 1); //减少某位置处的值
pq.heapDecreaseKey(2, 0); //减少某位置处的值
pq.printAll();
pq.heapDelete(0);
pq.printAll();
}
public static void heapInsert(int key) //插入一个新元素值key
{
int len = arr.length;
int[] newArr = new int[len+1];
for(int i=0;i<len;i++)
{
newArr[i] = arr[i];
}
newArr[len] = -1;
arr = newArr;
heapIncreaseKey(len, key);
}
public static void heapDelete(int pos) //删除堆中指定位置的元素
{
int len = arr.length;
if(pos>len)
{
System.out.println(pos+" is out of boundry!");
return;
}
int key = arr[len-1];
len--;
if(key>arr[pos])
{
arr = deleteLastElement(arr);
heapIncreaseKey(pos, key);
}
else
{
arr[pos] = key;
arr = deleteLastElement(arr);
//max_heapify(arr, len, pos);
heapDecreaseKey(pos, key);
}
}
public static void heapIncreaseKey(int pos, int key) //将pos位置处的值增加为key
{
if(key<arr[pos])
{
System.out.println("new key is smaller than current key");
return;
}
arr[pos] = key;
int temp;
while(pos>=0 && arr[(pos-1)/2]<arr[pos])
{
temp = arr[(pos-1)/2];
arr[(pos-1)/2] = arr[pos];
arr[pos] = temp;
pos = (pos-1)/2;
}
}
public static void heapDecreaseKey(int pos, int key) //将pos位置处的值减小为key
{
if(key>arr[pos])
{
System.out.println("new key is bigger than current key");
return;
}
arr[pos] = key;
max_heapify(arr, arr.length, pos);
}
public static int heapExtractMax() //删除并返回具有最大键字的元素
{
int len = arr.length;
int max = arr[0];
arr[0] = arr[len-1];
arr = deleteLastElement(arr);
max_heapify(arr, len-1, 0);
return max;
}
private static int[] deleteLastElement(int[] arr) //删除数组的最后一个元素
{
int[] newArr = new int[arr.length-1];
for(int i=0;i<arr.length-1;i++)
{
newArr[i] = arr[i];
}
return newArr;
}
public static void printAll()
{
for(int a : arr)
System.out.print(a+" ");
System.out.println();
}
public static int heapMaximum() //返回S中的具有最大键字的元素
{
return arr[0];
}
public static void heapSort(int[] arr) //堆排序
{
int hLen = arr.length;
int temp;
buildMaxHeap(arr);
while(hLen>1)
{
temp=arr[hLen-1];
arr[hLen-1]=arr[0];
arr[0]=temp;
hLen--;
max_heapify(arr, hLen, 0);
}
}
private static void buildMaxHeap(int[] arr) //从无序数组中构造一个最大堆, n*lgn
{
int hLen = arr.length;
int begin= hLen/2-1;
for(int i=begin;i>=0;i--)
{
max_heapify(arr,hLen, i);
}
}
private static void max_heapify(int[] arr, int hLen, int i) //用于调整堆,维护最大堆的性质,lgn
{
int left = 2*i+1; //i的左孩子,因为数组中下标是从0开始的
int right =2*i+2; //i的右孩子,因为数组中下标是从0开始的
int largest=i;
//int temp;
if(left<hLen && arr[left]>arr[i])
{
largest = left;
}
if(right<hLen && arr[right]>arr[largest])
{
largest = right;
}
if(i!=largest)
{
int temp=arr[largest];
arr[largest]=arr[i];
arr[i]=temp;
max_heapify(arr, hLen, largest);
}
}
}