【排序算法】堆排序

參考來自:堆排序及分析

package sort.algorithm.heap;

public class Heap
{
	// 堆排序,它組合了歸併排序的時間效率和快速排序的控件效率。和歸併排序一樣,堆排序
	// 的最差情況運行時間爲O(nlogn),和快速排序一樣它不需要額外的數組
	
	public static void heapsort(int[] data, int n)
	{
		int unsorted; // 數組中未排序部分的大小
		int temp;     // 在交換兩個數組位置時使用
		
		makeHasp(data, n);
		
		unsorted = n;
		show(data);
		while (unsorted > 1)
		{
			unsorted--;
			
			temp = data[0];
			data[0] = data[unsorted];
			data[unsorted] = temp;
			show(data);
			reheapifDown(data , unsorted);
		}
	}
	
	// 向下堆重排
	// data中的值重新排列了,使得data的前n個元素現在形成了堆
	// 通過持續地交換不協調元素和它的最大孩子節點起作用的。
	private static void reheapifDown(int[] data, int nlength)
	{
		int current;                 // 要往下移動的節點的下標
		int bigChiledIndex;          // 當前節點的孩子中,較大一個的下標
		boolean heapOkey;            // 當堆正確時爲true
		
		current = 0;
		heapOkey = false;
		
		// 當不協調元素到達葉子節點或不協調元素大於他的兩個孩子時,交換停止
		while ((!heapOkey)&&((current*2 + 1) < nlength))
		{
			// 將bigChiledIndex設置爲current節點的孩子中較大結點的下標
			 if ((2*current+2) < nlength )
			 {
				if (data[current*2 +1] > data[current*2 +2])
				{
					bigChiledIndex = current*2+1;
				}else {
					bigChiledIndex = current*2+2;
				}
			 } else {
				// 如果只有一個節點那麼bigChildIndex將被設置成這個孩子的下標
				bigChiledIndex = current*2+1;
			 }
			 
			 if (data[current] < data[bigChiledIndex])
			 { 
				System.out.println("*"+data[current]+","+data[bigChiledIndex]);
				int temp = data[current];
				data[current] = data[bigChiledIndex];
				data[bigChiledIndex] = temp;
				
				current = bigChiledIndex;
			 } else {
				heapOkey = true;
			 }
			 show(data);
		}
	}

	// 向上堆重排(data中的元素已經重新排列,是的由數組表示的完全二叉樹成爲堆)
	private static void makeHasp(int[] data, int n)
	{
		int i,k;
		int temp;
		
		for (i = 1;i < n;i++)
		{
			k = i;
			
			// data[k]還不是跟,data[k]比它的雙親大
			while (k != 0 && data[k] > data[parent(k)])
			{
				temp = data[k];
				data[k] = data[parent(k)];
				data[parent(k)] = temp;
				k = parent(k);
			}
		}
	}
	
	// k節點的雙親節點的下標
	private static int parent(int k)
	{
		return (k-1)/2;
	}
	
	public static void show(int[] data)
	{
		for (int i = 0; i < data.length; i++)
		{	
			System.out.print(data[i] + ",");
		} 
		System.out.println();
	}
	
	public static void main(String[] args)
	{
		int data[] = {80, 30, 60, 50, 40, 70, 20, 10, 5, 0};
		heapsort(data,10);
		show(data);
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章