排序算法之堆排序

1.什麼是堆

堆是完全二叉樹。堆分爲最大堆和最小堆。最大堆是根節點大於等於左右子樹;最小堆是根節點小於等於左右子樹。存儲堆最常用的數據結構是數組:所以最大堆的表示:array[i] >= array[2 * i] && array[i] >= array[2 * i + 2];最小堆的表示:array[i] <= array[2 * i] && array[i] <= array[2 * i + 2]。因爲用數組存儲且堆是是完全二叉樹,所以其根節點的索引範圍是0-array.length / 2

2.堆排序的步驟

1)初始化堆,即建立無須的最大堆或最小堆

2)將堆頂元素和最後一個元素交換,重新調整0至n-1節點,使其成爲堆

3)重複步驟2)

3.堆排序的實現

第一步建堆,第二步交換堆頂和最後一個元素,第三步調整其餘元素使其成爲堆

<pre name="code" class="html">public static void heapSort(int[] array) {
		// build the initial heap
		buildHeap(array);
		// swap the first and the last node
		for (int i = array.length - 1; i >= 0; i--) {
			swap(array, 0, i);
			adjustHeap(array, 0, i);
		}
	}

初始化堆的時候,也是通過不斷的調整,使其成爲堆

private static void buildHeap(int[] array) {
		for (int i = array.length / 2; i >= 0 ; i--) {
			adjustHeap(array, i, array.length);
		}
	}

	private static void adjustHeap(int[] array, int rootIndex, int length) {
		int leftIndex = 2 * rootIndex + 1;
		int rightIndex = 2 * rootIndex + 2;
		int maxIndex = rootIndex;
		// if the node is left, no adjust
		if (maxIndex <= length / 2) {
			// find the max number index in rootIndex, leftIndex, rightIndex
			if (leftIndex < length && array[leftIndex] > array[maxIndex]) {
				maxIndex = leftIndex;
			}
			if (rightIndex < length && array[rightIndex] > array[maxIndex]) {
				maxIndex = rightIndex;
			}
			// make the root is max
			if (maxIndex != rootIndex) {
				swap(array, rootIndex, maxIndex);
				// make sure the heap after swap
				adjustHeap(array, maxIndex, length);
			}
		}
	}

調整堆的代碼思路比較明確:比較堆頂和左右子樹的大小,將最大的放在堆頂,若交換之後的葉子節點也有子樹,則繼續比較。

以上代碼使用的是遞歸。

下面使用的非遞歸的方式

private static void adjustHeapNon(int[] array, int rootIndex, int length) {
		int maxIndex = rootIndex;
		// if the node is left, no adjust
		while (maxIndex <= length / 2) {
			int leftIndex = 2 * rootIndex + 1;
			int rightIndex = 2 * rootIndex + 2;
			// find the max number index in rootIndex, leftIndex, rightIndex
			if (leftIndex < length && array[leftIndex] > array[maxIndex]) {
				maxIndex = leftIndex;
			}
			if (rightIndex < length && array[rightIndex] > array[maxIndex]) {
				maxIndex = rightIndex;
			}
			// make the root is max
			if (maxIndex != rootIndex) {
				swap(array, rootIndex, maxIndex);
				rootIndex = maxIndex;
			} else {
				break;
			}
		}
	}

參考資料:

http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html

点赞