堆排序

/**
     * 可以用一維數組表示堆heap,但是並不是一維數組就是堆。要成爲堆必須具備一個性質: 數組中的元素滿足,k[i]<=k[2*i] &&
     * k[i]<=k[2*i+1]
     * 如果當前堆的的根節點爲堆中的最大值,而其他的左右孩子節點都不大於父節點,則稱該堆爲大根堆。同理,小根堆爲根節點爲堆中的最小值
     * ,而左右孩子節點均不小於父節點。
     * 
     * @param pArr
     */
    static void heapSort(int[] pArr) {
        for(int i=0,len=pArr.length;i<len;i++){
            heapAdjust(pArr, i);
        }
    }
    /**
     * 這裏要注意堆調整時,是根據數組中開始下標進行決定的。
     * @param pArr
     * @param s
     */
    static void heapAdjust(int[] pArr, int s) {
        int tmp = 0, len = pArr.length - 1;
        int i = len;
        while (i > s) {
            int k = (i-s-1) / 2+s; // 找父節點,(i-s-1) / 2在當前虛擬子樹中的父節點在數組中的位置,(i-s-1) / 2+s爲在pArr中數組的下標值。
            if (!lt(pArr[i], pArr[k])) {
                // 調整父節點
                tmp = pArr[i]; 
                pArr[i] = pArr[k];
                pArr[k] = tmp;

                //調整子節點
                if ((2 * i + 1-s) < len && !lt(pArr[2 * i + 1-s], pArr[i])) {//找左孩子
                    tmp = pArr[i];
                    pArr[i] = pArr[2 * i + 1];
                    pArr[2 * i + 1] = tmp;
                }
                if ((2 * i + 2-s) < len && !lt(pArr[2 * i + 2-s], pArr[i])) {//找右孩子
                    tmp = pArr[i];
                    pArr[i] = pArr[2 * i + 2-s];
                    pArr[2 * i + 2-s] = tmp;
                }
            }
            i--;
        }
    }

    static void array2LitterHeap(int[] pArr) {
        int tmp = 0, len = pArr.length - 1;
        int i = len;
        while (i > 0) {
            int k = (i - 1) / 2;
            if (lt(pArr[i], pArr[k])) {
                tmp = pArr[i];
                pArr[i] = pArr[k];
                pArr[k] = tmp;
                if ((2 * i + 1) < len && lt(pArr[2 * i + 1], pArr[i])) {
                    tmp = pArr[i];
                    pArr[i] = pArr[2 * i + 1];
                    pArr[2 * i + 1] = tmp;
                }
                if ((2 * i + 2) < len && lt(pArr[2 * i + 2], pArr[i])) {
                    tmp = pArr[i];
                    pArr[i] = pArr[2 * i + 2];
                    pArr[2 * i + 2] = tmp;
                }
            }
            i--;
        }
    }

    static void array2BiggerHeap(int[] pArr) {
        int tmp = 0, len = pArr.length - 1;
        int i = len;
        while (i > 0) {
            int k = (i - 1) / 2;
            if (!lt(pArr[i], pArr[k])) {
                tmp = pArr[i];
                pArr[i] = pArr[k];
                pArr[k] = tmp;
                if ((2 * i + 1) < len && !lt(pArr[2 * i + 1], pArr[i])) {
                    tmp = pArr[i];
                    pArr[i] = pArr[2 * i + 1];
                    pArr[2 * i + 1] = tmp;
                }
                if ((2 * i + 2) < len && !lt(pArr[2 * i + 2], pArr[i])) {
                    tmp = pArr[i];
                    pArr[i] = pArr[2 * i + 2];
                    pArr[2 * i + 2] = tmp;
                }
            }
            i--;
        }
    }

    private static boolean lt(int i, int j) {
        return i - j <= 0 ? true : false;
    }

    static void print(int[] pArr) {
        for (int var : pArr) {
            System.out.print(var + "  ");
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章