堆排序Heapsort的Java代碼

Heapsort排序思路

將整個數組看做一個二叉樹heap, 下標0爲堆頂層, 下標1, 2爲次頂層, 而後每層就是"3,4,5,6", "7, 8, 9, 10, 11, 12, 13, 14", ..., 對於其中的每個非葉子節點, 其子節點的下標爲 2 * pos + 1 和 2 * pos + 2java

循環進行如下工做:數組

  1. 標記當前堆的右邊界
  2. 將堆初始化爲大頂堆
  3. 將堆頂置換到右邊界, 同時將右邊界左移一位(即將堆縮小一格)

將堆初始化爲大頂堆的處理this

  1. 從最後一個非葉子節點開始, 其下標爲  length / 2 - 1, length爲當前的堆大小, 往前挨個處理
  2. 檢查節點值, 對節點與其子節點的值大小i進行比較, 若是子節點值比當前節點大, 將最大值的那個子節點換上來
  3. 若是發生了交換, 那麼要對發生交換的這個子節點位置也進行檢查, 若是還有交換, 則繼續往下查, 直到達到葉子節點

 

public class DemoHeapSort {
    // 待排序的數組
    private int[] ints;
    // 當前堆的右邊界(下標)
    private int limit;

    public DemoHeapSort(int ... ints) {
        this.ints = ints;
        this.limit = ints.length - 1;
    }

    public void sortAll() {
        while (limit > 0) {
            resort();
            swap(0, limit);
            limit--;
        }
    }

    public void resort() {
        // 起點pos爲當前堆length / 2 - 1
        for (int i = (limit + 1) / 2 - 1; i >= 0; i--) {
            int pos = i;
            while (true) {
                pos = check(pos);
                if (pos == 0) {
                    break;
                }
            }
        }
    }

    /**
     * 檢查pos位置, 自上而下判斷是否都知足大頂堆的要求
     * 其左右子節點的下標爲 2*pos+1 和 2*pos+2
     *
     * @param pos 當前要檢查的下標
     * @return 若是無調整, 則返回0, 若是有調整, 則返回被調整的子節點下標
     */
    private int check(int pos) {
        int posLeft = 2 * pos + 1;
        int posRight = 2 * pos + 2;
        if (posLeft > limit) { // 沒有子節點
            return 0;
        }
        if (posRight > limit) { // 僅有左節點
            if (ints[pos] < ints[posLeft]) {
                swap(pos, posLeft);
                return posLeft;
            } else {
                return 0;
            }
        }
        // 左右節點都有
        if (ints[posLeft] > ints[posRight]) {
            if (ints[pos] < ints[posLeft]) {
                swap(pos, posLeft);
                return posLeft;
            } else {
                return 0;
            }
        } else {
            if (ints[pos] < ints[posRight]) {
                swap(pos, posRight);
                return posRight;
            } else {
                return 0;
            }
        }
    }

    public void print() {
        for (int a : ints) {
            System.out.printf("%3d", a);
        }
        System.out.print("\n");
    }

    private void swap(int a, int b) {
        int tmp = ints[a];
        ints[a] = ints[b];
        ints[b] = tmp;
    }

    public static void main(String[] args) {
        DemoHeapSort hs = new DemoHeapSort(10, 97, 9, 1,63, 64, 8, 17, 33, 7, 21, 0, 7, 75, 13, 18, 2, 99, 87);
        hs.sortAll();
        hs.print();
    }
}

.3d

相關文章
相關標籤/搜索