堆排序的基本思想是: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] -----------------------------------------------------
參考文檔:排序