您的位置:首页 > 其它

算法导论(第三版)第六章 堆排序的全部实现(堆排序,优先队列)

2014-05-19 00:00 351 查看
摘要: 我正在做一个开源项目:《算法导论》(第三版)的答案以及常用算法,项目地址:http://git.oschina.net/jiangkun/Introduction_to_Algorithms-Third_Edition-Answers
本文均来自项目。

本文章代码来自于项目: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);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: