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

原创
2014/05/19 16:24
阅读数 565

本文章代码来自于项目: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);
		}		
	}
}


展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部