背景介紹:
是指利用堆這種數據結構所設計的一種排序算法。堆積是一個近似完全二叉樹的結構,并同時滿足堆積的性質:即子結點的鍵值或索引總是小于(或者大于)它的父節點。算法規則:
堆是具有下列性質的完全二叉樹:每個結點的值都大于或等于其左右孩子結點的值,稱為大頂堆;或者每個結點的值都小于或等于其左右孩子結點的值,稱為小頂堆。將待排序的序列構造成一個大頂堆。此時,整個序列的最大值就是堆頂的根節點。將它移走(其實就是將其與堆數組的末尾元素交換,此時末尾元素就是最大值),然后將剩余的n-1個序列重新構造成一個堆,這樣就會得到n個元素中的次最大值。如此反復執行,就能得到一個有序序列了。-
代碼實現(Java版本)
/** * 堆排序 */ private static void heapSort(int[] arr) { // 將待排序的序列構建成一個大頂堆 for (int i = arr.length / 2; i >= 0; i--){ heapAdjust(arr, i, arr.length); } // 逐步將每個最大值的根節點與末尾元素交換,并且再調整二叉樹,使其成為大頂堆 for (int i = arr.length - 1; i > 0; i--) { swap(arr, 0, i); // 將堆頂記錄和當前未經排序子序列的最后一個記錄交換 heapAdjust(arr, 0, i); // 交換之后,需要重新檢查堆是否符合大頂堆,不符合則要調整 } } /** * 構建堆的過程 * @param arr 需要排序的數組 * @param i 需要構建堆的根節點的序號 * @param n 數組的長度 */ private static void heapAdjust(int[] arr, int i, int n) { int child; int father; for (father = arr[i]; leftChild(i) < n; i = child) { child = leftChild(i); // 如果左子樹小于右子樹,則需要比較右子樹和父節點 if (child != n - 1 && arr[child] < arr[child + 1]) { child++; // 序號增1,指向右子樹 } // 如果父節點小于孩子結點,則需要交換 if (father < arr[child]) { arr[i] = arr[child]; } else { break; // 大頂堆結構未被破壞,不需要調整 } } arr[i] = father; } // 獲取到左孩子結點 private static int leftChild(int i) { return 2 * i + 1; } // 交換元素位置 private static void swap(int[] arr, int index1, int index2) { int tmp = arr[index1]; arr[index1] = arr[index2]; arr[index2] = tmp; }
算法學習:堆排序
最后編輯于 :
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。