【排序算法】堆排序

参考来自:堆排序及分析

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);
	}
}


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