堆排序 Java實現
阿新 • • 發佈:2019-02-13
堆排序是利用堆這種資料結構而設計的一種排序演算法,堆排序是一種選擇排序,它的最壞,最好,平均時間複雜度均為O(nlogn),它也是不穩定排序。
堆是具有以下性質的完全二叉樹:每個結點的值都大於或等於其左右孩子結點的值,稱為大頂堆;或者每個結點的值都小於或等於其左右孩子結點的值。
堆排序的基本思路:
a.將無需序列構建成一個堆,根據升序降序需求選擇大頂堆或小頂堆;
b.將堆頂元素與末尾元素交換,將最大元素"沉"到陣列末端;
c.重新調整結構,使其滿足堆定義,然後繼續交換堆頂元素與當前末尾元素,反覆執行調整+交換步驟,直到整個序列有序。
升序排序,則構建大頂堆。
package nuc.edu.lisheng; import java.util.Arrays; public class HeapSort { public static void main(String[] args) { int[] a = { 58, 4, 5, 9, 36, 27, 1, 3, 58 }; HeapSortFianl(a); System.out.println(Arrays.toString(a)); } //是否排序完成 public static boolean ifend(int[] a) { // true代表還要繼續,即沒有排序好 boolean ifend = true; A: for (int index = a.length - 1; index > 0; index--) { if (a[index] < a[index - 1]) { ifend = false; break A; } } return ifend; } //判斷a是否為奇數。(從0開始)完全二叉樹中奇數索引在左,偶數索引在右。左右對應的交換操作斌不相同 public static boolean odd(int a) { if (a % 2 == 0) { return false; } else { return true; } } //左右節點與父節點比較大小,交換 public static void sortHeap(int[] a, int i, int changeIndex) { //如果是偶數 if (!odd(i)) { int left = i - 1; int father = (i - 1) / 2; if (a[i] > a[father]) { int num = a[i]; a[i] = a[father]; a[father] = num; } if (a[left] > a[father]) { int num = a[left]; a[left] = a[father]; a[father] = num; } } else { //如果是奇數,且在可操作的最後一位,那麼沒有右節點,直接比較左節點即可 if (i == changeIndex) { int father = i / 2; if (a[i] > a[father]) { int num = a[i]; a[i] = a[father]; a[father] = num; } } else { //左右都有,都比較 int right = i + 1; int father = i / 2; if (a[i] > a[father]) { int num = a[i]; a[i] = a[father]; a[father] = num; } if (a[right] > a[father]) { int num = a[right]; a[right] = a[father]; a[father] = num; } } } } public static void getMaxHeap(int[] a, int changeIndex) { //從可操作的最後一位往後比較,直到1為止。 for (int i = changeIndex; i > 0; i--) { sortHeap(a, i, changeIndex); } } //可操作的最後一位與守衛交換 public static void changeFirstAndEnd(int[] a, int changeIndex) { int num = a[changeIndex]; a[changeIndex] = a[0]; a[0] = num; } public static void HeapSortFianl(int[] a) { int changeIndex = a.length - 1; A: while (true) { getMaxHeap(a, changeIndex); changeFirstAndEnd(a, changeIndex); changeIndex--; if (ifend(a)) { break A; } } } }
結果: