[編程題] 堆排序(數組與大頂堆的轉換過程)


[編程題] 堆排序(數組與大頂堆的轉換過程)

參考這個大神講解的堆排序,思路清晰


數組和樹的關系

題目信息

​ 如何把數組轉換為二叉樹呢?

思路

數組對應樹的公式:

數組一個節點的左孩子:2*i+1

數組一個節點的右孩子:2*i+2

某節點的父親節點:(i-1)/2

注意


數組轉為大頂堆

思路

思路:在每一個節點進入的時候,就會比較其與父節點的大小關系,調整樹結構。(這里即是交換數組中的元素),建立出了大頂堆的數組。

建立大頂堆的時間復雜度

時間復雜度:O(nlogn)

Java代碼

package Demo11_堆;

import java.lang.reflect.Parameter;
import java.util.Arrays;

/**
 * @author jiyongjia
 * @create 2020/8/9 - 13:23
 * @descp:
 */
public class P3_堆排序 {
    public static void main(String[] args) {
        int[] arr = {10, 131,3,42,221,3,2,-1,0,-32, 40, 5, 2, 18};
//        heapify(arr,arr.length,0);
//        heap_build(arr);
        heapSort(arr);
        System.out.println(Arrays.toString(arr));
    }
    /**
     * 1 heapify操作(需要按照傳入的i的父節點進行遞歸的heapify操作)
     * @param arr 數組
     * @param n  數組的個數
     * @param i  傳入的父節點的索引號(如0)
     */
    public static void heapify(int[] arr,int n,int i){
        //遞歸的出口
        if(i>=n){return;}
        int l = 2*i+1;
        int r = 2*i+2;
        int maxIndex = i;
        if(l<n && arr[l]>arr[maxIndex]){ //TODO:注意
            maxIndex = l;
        }
        if(r<n && arr[r]>arr[maxIndex]){
            maxIndex = r;
        }
        if(maxIndex != i){
            swap(arr,i,maxIndex);//只有不等才交換
            //遞歸處理
            heapify(arr,n,maxIndex);
        }
    }

    public static void swap(int[] arr,int i,int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    /**
     *2 使用heapify從最后一個非葉子節點往前遍歷每個父節點,然后生成一個大頂堆
     * @param arr
     */
    public static void heap_build(int[] arr){
        int n = arr.length;
        int lastNodeParent = (n-1-1)/2;   //根據公式計算最后一個非葉子節點(即最后一個父節點)
        for (int i = lastNodeParent; i >=0 ; i--) {
            heapify(arr,arr.length,i);   //倒着推的從下往上構建好堆
        }
    }

    //3 構建好堆之后,每次把堆頂的元素和最后一個元素交換,得到一個最大值放最后了
    public static void heapSort(int[] arr){
        heap_build(arr);//先構造出一個堆
        for(int i=arr.length-1;i>=0;i--){
            //經過交換,最大的堆頂到了最后一個元素的地方
            swap(arr,i,0);
            //下次heapfify就不考慮這個最后的這個堆即可
            heapify(arr,i,0); //從0開始heapify這個堆來調整堆。此次最大值已經在最后位置了,所以這里傳的數組長度為i
        }
    }
}

輸出:

int[] arr = {10, 131,3,42,221,3,2,-1,0,-32, 40, 5, 2, 18};

image-20200809142235734


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM