算法導論(第三版)第六章 堆排序的所有實現(堆排序,優先隊列)

本文章代碼來自於項目:http://git.oschina.net/jiangkun/Introduction_to_Algorithms-Third_Edition-Answersjava

歡迎你們一塊兒參與!我會不定時更新!git

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);
		}		
	}
}
相關文章
相關標籤/搜索