本篇文章主要用圖片的形式講解了堆排序流程,之後用Java代碼實現堆排序並且分析時間複雜度,具有一定參考價值,有興趣的朋友可以了解一下。
一、導論
我們從陣列下標0開始,不像二元堆從數組下標1開始。
程式碼實作
public class Heapsort { public static void main(String[] args) { Integer[] integers = {7, 1, 13, 9, 11, 5, 8}; System.out.println("原序列:" + Arrays.toString(integers)); heapsort(integers); System.out.println("排序后:" + Arrays.toString(integers)); } public static <T extends Comparable<? super T>> void heapsort(T[] a) { if (null == a || a.length == 0) { throw new RuntimeException("数组为null或长度为0"); } //构建堆 for (int i = a.length / 2 - 1; i >= 0; i--) { percDown(a, i, a.length); } //deleteMax for (int i = a.length - 1; i > 0; i--) { swapReferences(a, 0, i); percDown(a, 0, i); } } /** * 下滤的方法 * * @param a:待排序数组 * @param i:从哪个索引开始下滤 * @param n :二叉堆的逻辑大小 * @param <T> */ private static <T extends Comparable<? super T>> void percDown(T[] a, int i, int n) { int child; T tmp; for (tmp = a[i]; leftChild(i) < n; i = child) { child = leftChild(i); if (child != n - 1 && a[child].compareTo(a[child + 1]) < 0) { child++; } if (tmp.compareTo(a[child]) < 0) { a[i] = a[child]; } else { break; } } a[i] = tmp; } private static int leftChild(int i) { return 2 * i + 1; } /** * 交换数组中两个位置的元素 * * @param a:目标数组 * @param index1 :第一个元素下标 * @param index2 :第二个元素下标 * @param <T> */ private static <T> void swapReferences(T[] a, int index1, int index2) { T tmp = a[index1]; a[index1] = a[index2]; a[index2] = tmp; } } //输出结果 //原序列:[7, 1, 13, 9, 11, 5, 8] //排序后:[1, 5, 7, 8, 9, 11, 13]
時間複雜度:buildHeap使用O(N)的時間,元素下濾需要O(logN),需要下濾N-1次,所以總共需要O(N (N-1)logN) = O(NlogN)。 從過程可以看出,堆排序,不管最好,最壞時間複雜度都穩定在O(NlogN)。
空間複雜度:使用自身存儲,無疑是O(1)。
#本篇透過畫圖,說明堆排序的過程,清晰明了知道堆排序先經過堆序化,再透過deleteMax進行排序。其空間複雜度為O(1),時間複雜度穩定在O(NlogN)。
以上是Java學習之堆排序流程圖解以及程式碼講解的詳細內容。更多資訊請關注PHP中文網其他相關文章!