排序:堆排序

堆排序的基本思想是:html

        將待排序序列構形成一個大頂堆,此時,整個序列的最大值就是堆頂的根節點。將其與末尾元素進行交換,此時末尾就爲最大值。而後將剩餘n-1個元素從新構形成一個堆,這樣會獲得n個元素的次小值。如此反覆執行,便能獲得一個有序序列了。java

算法過程:算法

步驟一 構造初始堆。將給定無序序列構形成一個大頂堆(通常升序採用大頂堆,降序採用小頂堆)。數組

步驟二 將堆頂元素與末尾元素進行交換,使末尾元素最大。而後繼續調整堆,再將堆頂元素與末尾元素交換,獲得第二大元素。如此反覆進行交換、重建、交換。code

 

/**
 * 堆排序(此方法最後獲得的是升序的數組)
 * @param elements
 */
public static void heapSort(int[] elements) {
	int lastParentNodeIndex = 0;
	for(int tempLength = elements.length; tempLength > 1; tempLength--) {
		// 步驟1.構建大頂堆
		lastParentNodeIndex = (tempLength >> 1) - 1;
		for(int i = lastParentNodeIndex; i >= 0; i--) {
			// 從第一個非葉子結點從下至上,從右至左調整結構
			adjustHeap(elements, i, tempLength);
		}
		System.out.println("構建大頂堆:"+Arrays.toString(elements));
		// 交換堆頂元素與末尾元素
		swapElement(elements, 0, tempLength-1);
		System.out.println("交換堆頂元素與末尾元素:"+Arrays.toString(elements));
		System.out.println("-----------------------------------------------------");
	}
}

private static void adjustHeap(int[] elements, int parentNodeIndex, int length) {
	int leftNodeIndex = (parentNodeIndex << 1) + 1;
	int rightNodeIndex = leftNodeIndex + 1;
	if((length - 1) >= rightNodeIndex) {
		// parentNodeIndex指定的節點有左右兩個子節點
		// 先比較左右連個子節點的元素大小,取大的子節點與父節點比較,若子節點的元素大於父節點,則把這兩個元素交換
		if(elements[leftNodeIndex] >= elements[rightNodeIndex]) {
			if(elements[leftNodeIndex] > elements[parentNodeIndex]) {
				swapElement(elements,leftNodeIndex, parentNodeIndex);
				adjustHeap(elements, leftNodeIndex, length);
			}
		} else {
			if(elements[rightNodeIndex] > elements[parentNodeIndex]) {
				swapElement(elements, rightNodeIndex, parentNodeIndex);
				adjustHeap(elements, rightNodeIndex, length);
			}
		}
	} else if((length - 1) >= leftNodeIndex) {
		// parentNodeIndex指定的節點只有左邊一個個子節點
		// 直接比較左邊子節點與父節點的大小,若子節點的元素大於父節點,則把這兩個元素交換
		if(elements[leftNodeIndex] > elements[parentNodeIndex]) {
			swapElement(elements,leftNodeIndex, parentNodeIndex);
			adjustHeap(elements, leftNodeIndex, length);
		}
	} else {
		// 元素下標超出了參數length-1,什麼事都不用作
	}
}
private static void swapElement(int[] elements, int i, int j) {
	int temp = elements[i];
	elements[i] = elements[j];
	elements[j] = temp;
}

調用方法:htm

public static void main(String[] args) {
	int[] array = {82 ,31 ,29 ,71, 72, 42, 64, 5, 110};
	heapSort(array);
}

結果:blog

構建大頂堆:[110, 82, 64, 71, 72, 42, 29, 5, 31]
交換堆頂元素與末尾元素:[31, 82, 64, 71, 72, 42, 29, 5, 110]
-----------------------------------------------------
構建大頂堆:[82, 72, 64, 71, 31, 42, 29, 5, 110]
交換堆頂元素與末尾元素:[5, 72, 64, 71, 31, 42, 29, 82, 110]
-----------------------------------------------------
構建大頂堆:[72, 71, 64, 5, 31, 42, 29, 82, 110]
交換堆頂元素與末尾元素:[29, 71, 64, 5, 31, 42, 72, 82, 110]
-----------------------------------------------------
構建大頂堆:[71, 31, 64, 5, 29, 42, 72, 82, 110]
交換堆頂元素與末尾元素:[42, 31, 64, 5, 29, 71, 72, 82, 110]
-----------------------------------------------------
構建大頂堆:[64, 31, 42, 5, 29, 71, 72, 82, 110]
交換堆頂元素與末尾元素:[29, 31, 42, 5, 64, 71, 72, 82, 110]
-----------------------------------------------------
構建大頂堆:[42, 31, 29, 5, 64, 71, 72, 82, 110]
交換堆頂元素與末尾元素:[5, 31, 29, 42, 64, 71, 72, 82, 110]
-----------------------------------------------------
構建大頂堆:[31, 5, 29, 42, 64, 71, 72, 82, 110]
交換堆頂元素與末尾元素:[29, 5, 31, 42, 64, 71, 72, 82, 110]
-----------------------------------------------------
構建大頂堆:[29, 5, 31, 42, 64, 71, 72, 82, 110]
交換堆頂元素與末尾元素:[5, 29, 31, 42, 64, 71, 72, 82, 110]
-----------------------------------------------------

 

參考文檔:排序

http://www.javashuo.com/article/p-wtyhbkog-dg.htmlelement

https://mp.weixin.qq.com/s/vgpKzmEjuJkhFy-NfpvURQ文檔