堆排序Java示例

堆排序是指利用堆這種數據結構所設計的一種排序算法。堆的特點是子結點總是小於(或者大於)它的父節點,根節點最大的堆叫做最大堆,根節點最小的堆叫做最小堆。根據升序或降序的排序需求選擇使用最大堆還是最小堆,本文以升序排列爲例,所以選用最大堆。

堆排序的基本思想是:將原始序列先調整爲一個最大堆,這樣根頂元素就是整個序列的最大值;將其與末尾元素交換,這樣該序列最大元素就歸位了;將剩下的N-1個元素再調整爲最大堆,再次交換根頂元素和本次末尾元素,這樣次大值也歸位了;反覆循環,直到整個序列都有序。

java示例:

public class HeapSort {

    public static void main(String[] args) {
        int[] arr = {1,3,2,6,4,66,32,65,34,67,45,77,78,36,56};
        System.out.println("排序前:");
        System.out.println(Arrays.toString(arr));
        sort(arr);
        System.out.println("排序後:");
        System.out.println(Arrays.toString(arr));
    }

    public static void sort(int[] arr) {
        //構建最大堆
        for (int i = arr.length/2 - 1; i >= 0; i--) {
            handleHeap(arr, i, arr.length);//從最末尾的非葉子節點,自右至左,自下而上調整
        }
        for (int j = arr.length - 1; j > 0; j--) {
            swap(arr, 0, j);//交換根頂元素和末尾元素
            handleHeap(arr, 0, j);//重新調整成最大堆
        }
    }

    //調整最大堆(建立在最大堆已構建的基礎上)
    public static void handleHeap(int[] arr, int i, int length) {
        int temp = arr[i];//先取出當前元素i
        for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {//從i結點的左子結點開始,也就是2i+1處開始
            if (k + 1 < length && arr[k] < arr[k + 1]) {//如果左子結點小於右子結點,k指向右子結點
                k++;
            }
            if (arr[k] > temp) {//如果子節點大於父節點,將子節點值賦給父節點(不用進行交換)
                arr[i] = arr[k];
                i = k;
            } else {
                break;
            }
        }
        arr[i] = temp;//將temp值放到最終的位置
    }

    //交換數組中兩個元素
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

執行結果:

排序前:
[1, 3, 2, 6, 4, 66, 32, 65, 34, 67, 45, 77, 78, 36, 56]
排序後:
[1, 2, 3, 4, 6, 32, 34, 36, 45, 56, 65, 66, 67, 77, 78]

Process finished with exit code 0

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章