【Java】 大話數據結構(16) 排序算法(3) (堆排序)

本文根據《大話數據結構》一書,實現了Java版的堆排序html

更多:數據結構與算法合集java

基本概念

  堆排序種的堆指的是數據結構中的堆,而不是內存模型中的堆。算法

  :能夠當作一棵徹底二叉樹,每一個結點的值都大於等於(小於等於)其左右孩子結點的值,稱爲大頂堆小頂堆)。數據結構

大頂堆(左)與小頂堆(右)ide

  堆排序的基本思想:將帶排序的序列構形成大頂堆,最大值爲根結點。將根結點與最後一個元素交換,對除最大值外的剩下n-1個元素從新構形成大頂堆,能夠得到次大的元素。反覆執行,就能夠獲得一個有序序列了。函數

  構造大頂堆的方法post

  1.首先複習徹底二叉樹的性質,層序遍歷,當第一個元素索引從0開始時,索引爲i的左孩子的索引是 (2*i+1),右孩子的索引是 (2*i+2)。測試

  2.設計一個函數heapAdjust(),對於一個序列(除了第一個根結點外,其他結點均知足最大堆的定義),經過這個函數能夠將序列調整爲正確的大頂堆。url

  3.正式構造:將帶排序的序列當作一棵徹底二叉樹的層序遍歷,咱們從下往上,從右往左,依次將每一個非葉子結點看成根結點,使用heapAdjust()調整成大頂堆。spa

  具體細節的實現參閱代碼,比較清楚,再也不贅述。

完整Java代碼

(含測試代碼)

/**
 * 
 * @Description 堆排序
 *
 * @author yongh
 * 
 */
public class HeapSort {
	public void heapSort(int[] arr) {
		if(arr==null || arr.length<=0)
			return;
		int len=arr.length;
		for(int i=len/2-1;i>=0;i--) { //從最後一個父結點開始構建最大堆
			heapAdjust(arr,i,len-1);
		}
		for(int i=len-1;i>=0;i--) {
			int temp=arr[0];
			arr[0]=arr[i];
			arr[i]=temp;
			heapAdjust(arr, 0, i-1);
		}
	}
	
	
	/*
	 * 功能:調整堆爲最大堆
	 * [i……j]中,除了i以外,部分子樹都知足最大堆定義
	 */
	private void heapAdjust(int[] arr, int start, int end) {
		int temp=arr[start];
		int child=2*start+1;
		while(child<=end) {
			if(child+1<=end && arr[child+1]>arr[child])  //記得child+1<=end的判斷
				child++;  //較大的孩子
			if(arr[child]<=temp) 
				break;
			arr[start]=arr[child];
			start=child;
			child=child*2+1;
		}
		arr[start]=temp;	
		}
	
	// =========測試代碼=======
	public void test1() {
		int[] a = null;
		heapSort(a);
		System.out.println(Arrays.toString(a));
	}

	public void test2() {
		int[] a = {};
		heapSort(a);
		System.out.println(Arrays.toString(a));
	}

	public void test3() {
		int[] a = { 1 };
		heapSort(a);
		System.out.println(Arrays.toString(a));
	}

	public void test4() {
		int[] a = { 3, 3, 3, 3, 3 };
		heapSort(a);
		System.out.println(Arrays.toString(a));
	}

	public void test5() {
		int[] a = { -3, 6, 3, 1, 3, 7, 5, 6, 2 };
		heapSort(a);
		System.out.println(Arrays.toString(a));
	}

	public static void main(String[] args) {
		HeapSort demo = new HeapSort();
		demo.test1();
		demo.test2();
		demo.test3();
		demo.test4();
		demo.test5();
	}
}
	
	

  

null
[]
[1]
[3, 3, 3, 3, 3]
[-3, 1, 2, 3, 3, 5, 6, 6, 7]
HeapSort

 

複雜度分析

   構建堆的時間複雜度爲O(n);每次調整堆的時間爲O(logn),共要調整n-1次,因此重建堆的時間複雜度爲O(nlogn)。

  所以整體來講,堆排序的複雜度爲O(nlogn)。不過因爲記錄的比較和交換是跳躍式進行的,所以堆排序是不穩定的排序方法。

 

更多:數據結構與算法合集

相關文章
相關標籤/搜索