堆排序

堆排序算法步驟:
1、把無序數組構建成二叉堆。需要從小到大排序,則構建成最大堆;需要從大到小排序,則構建成最小堆。
2、循環刪除堆頂元素,替換到二叉堆的末尾,調整堆產生新的堆頂

複雜度

空間複雜度:因爲沒有開闢額外的集合空間,所以複雜度爲O(1)
時間複雜度 O(nlogn):
二叉堆的節點“下沉”是堆排序算法的基礎,這個複雜度是O(logn)
第1步,把無序數組構建成二叉堆,這一步的時間複雜度是O(n)
第2步,需要進行n-1次循環,每次循環調用一次下沉方法,所以第2步的計算規模是(n-1)*logn,所以整體的時間複雜度是O(nlogn)

和快排的區別
    相同點:平均時間複雜度都是O(nlogn),都是步穩定排序
    不同點:
        1、快排的最壞時間複雜度是O(n2平方),堆排序的最壞時間複雜度是O(nlogn)
        2、快排的評價空間複雜度O(logn),堆排序的空間複雜度是O(1)

public class HeapSoft {

    public static void downAdjust(int[] arr,int parentIndex,int length){
        int childIndex = parentIndex * 2 + 1;
        //保存父節點的值,用於最後賦值
        int temp = arr[parentIndex];
        while (childIndex < length){
            //如果又右孩子,且右孩子大於左孩子的值,則定位到右孩子
            if(childIndex + 1 < length && arr[childIndex + 1] > arr[childIndex]){
                childIndex ++ ;
            }
            //如果父節點大於任何一個孩子的值,則直接推出
            if(temp >= arr[childIndex]){
                break;
            }
            //無須真正交互,單向賦值即可
            arr[parentIndex] = arr[childIndex];
            parentIndex = childIndex;
            childIndex = 2 * childIndex + 1 ;
        }
        arr[parentIndex] = temp;
    }

    public static void heapSort(int[] arr){
        //把無序數組構建成最大堆
        for(int i=(arr.length - 2)/2;i>=0;i--){
            downAdjust(arr,i,arr.length);
        }
        System.out.println(Arrays.toString(arr));
        for (int i=arr.length - 1;i>0;i--){
            //最後一個元素和第一個元素進行交換
            int temp = arr[i];
            arr[i] = arr[0];
            arr[0] = temp;

            downAdjust(arr,0,i);
        }
    }

    public static void main(String[] args) {
        int[] arr = new int[]{1,3,2,6,5,7,8,9,10,0};
        heapSort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

 

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