算法 - 堆排序(大頂堆、小頂堆)

在這裏插入圖片描述

在這裏插入圖片描述

用的是順序存儲二叉樹,也就是數組實現的二叉樹,遍歷的時候按照的是二叉樹的形式

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

代碼實現

package tree;

import java.util.Arrays;

public class HeapSort {
    public static void main(String []args){
        int [] arr = {4, 6, 8, 5, 9,-1,-1,2,4,5,6,88};
        heapSort(arr);

    }

    //編寫堆排序方法
    public static void heapSort(int arr []){
        System.out.println("堆排序");
        int temp = 0;
        //建堆(第一次整體是無序的,需要從下往上,從左往右開始建大頂堆)

        for (int i = arr.length / 2 -1; i >= 0 ; i--) {
            adjustHeap(arr,i,arr.length);
        }

        
        //不斷交換重構大頂堆(因爲第一次重構的時候已經有序,交換後只是root節點無序,只需要把root節點的值放到他該去的位置即可,所以從頂點往下開始重構,然後循環)
        for (int j = arr.length -1; j > 0; j--) {
            //交換
            temp = arr[j];
            arr[j] = arr[0];
            arr[0] = temp;
            adjustHeap(arr,0,j);
        }

        System.out.println("數組:"+ Arrays.toString(arr));
    }

    //將數組(二叉樹),調整成大頂堆

    /**
     * 功能:{4, 6, 8, 5, 9} => i = 1 以6爲非葉子節點的 子樹 調整成大頂堆{4, 9, 8, 5, 6}(讓6與兩個孩子比較,比 6 大就交換),
     *      然後繼續調整傳入i = 0,以4位節點的樹調整成大頂堆(讓4與兩個孩子比較,比 4 大就交換)
     * @param arr   待調整的數組
     * @param i 非葉子節點在數組中的索引
     * @param length    對多少個元素進行調整(調整好的就不進行調整),length不斷減少
     */
    public static void adjustHeap(int arr [], int i, int length){
        int temp = arr[i]; //保存此非葉子節點
        //開始調整
        //說明k是i的左子節點
        for (int j = i * 2 + 1; j < length; j = j * 2 + 1) {
            if (j+1 < length && arr[j] < arr[j+1]){//說明左子節點小於右子節點
                j++; //j 指向右子節點
            }
            if (arr[j] > temp){//如果子節點大於父節點
                arr[i] = arr[j];//把較大的值附給當前節點
                i = j; //!!! i指向j,繼續循環比較
            }else {
                break;
            }
        }
        arr[i] = temp;
    }
}

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