1. 程式人生 > >常見排序算法-----堆排序

常見排序算法-----堆排序

交換 col .html int 自頂向下 [] ring cnblogs temp

 1     // 堆排序,升序用最大堆,降序用最小堆
 2     /*
 3      * 思路: 將數組構建成一個最大堆,從最後一個非葉子節點開始,將它和它的左右子節點中最大的節點相比較
 4      * 如果子節點大則進行交換,再找倒數第二個非葉子節點,同理。 當到倒數第三個葉子節點時,若發生交換
 5      * 則還應判斷交換過後有沒有對交換過的子節點發生影響,若有影響應進行調整。
 6      * 
 7      * 自底向上建立堆,自頂向下調整堆
 8      */
 9 
10     public static void main(String[] args) {
11         HeapSort hs = new
HeapSort(); 12 int[] arr = new int[] { 1, 4, 56, 2, 4, 6, 8, 9 }; 13 hs.heapSort(arr); 14 for (int i = 0; i < arr.length; i++) { 15 System.out.println(arr[i]); 16 } 17 } 18 19 public void heapSort(int[] arr) { 20 21 // 找到最後一個非葉子節點開始遍歷,建立最大堆
22 for (int i = arr.length - 2 >> 2; i >= 0; i--) { 23 adjustHeap(arr, i, arr.length); 24 25 } 26 27 for (int i = arr.length - 1; i > 0; i--) { 28 // 此時已經建立好最大堆,最大值在最上方,將其與最後一個元素進行交換,即將最大的元素排除,尋找剩余元素中的最大值 29 swap(arr, 0, i); 30 //
交換後重新調整堆結構 31 adjustHeap(arr, 0, i); 32 } 33 34 } 35 36 public void swap(int[] arr, int i, int j) { 37 int temp = arr[i]; 38 arr[i] = arr[j]; 39 arr[j] = temp; 40 } 41 42 /** 43 * 調整是建立在 已經建立好最大堆的基礎上 44 * 45 * @param arr 46 * @param i 47 * @param length 48 */ 49 public void adjustHeap(int[] arr, int i, int length) { 50 51 int temp = arr[i]; 52 for (int j = 2 * i + 1; j < length; j = j * 2 + 1) {// 從i節點的左子節點開始 53 if (j + 1 < length && arr[j] < arr[j + 1]) { // 如果存在右子節點,且右子節點大於左子節點 54 j++; // 如果是最小堆比較的是最小值 即條件改為 arr[j]>arr[j+1] j++ 55 } 56 if (arr[j] > temp) { // 如果最大的子節點大於父節點,交換(此處不需要交換直接賦值即可) //如果arr[j] 57 // <temp 進行交換 58 arr[i] = arr[j]; 59 i = j; 60 } else { 61 break; // 如果不大於說明不會對後面產生影響直接跳出循環 62 } 63 // 確定i最後所在的位置 將值賦予該位置 64 arr[i] = temp; 65 } 66 67 }

堆排序是一種不穩定排序,其中構建初始堆經推導復雜度為O(n),在交換並重建堆的過程中,需交換n-1次,而重建堆的過程中,根據完全二叉樹的性質,[log2(n-1),log2(n-2)...1]逐步遞減,近似為nlogn

詳情 http://www.cnblogs.com/chengxiao/p/6129630.html

常見排序算法-----堆排序