算法导论之第六章-堆排序

package test2018.test08;

import java.util.Random;

/**
* Filename: Class7Duipaixu.java Description: 堆排序:第一步,建堆,保证所有父节点大于子节点的值
* 第二步,取值:把根节点移到后面,然后移位
*
* @author: guzhangyan
* @date: 2018年8月7日 下午4:54:04
*/

public class Class7Duipaixu {
    public static void main(String[] args) {
        long stratTime = System.currentTimeMillis();
        int[] shuZu = new int[100000000];
        Random random = new Random();
        for (int i = 0; i < shuZu.length; i++) {
            shuZu[i] = random.nextInt(100);
        }
        jianDui(shuZu, 0);

        /*
         * for (int i = 1; 2 * i + 2 < shuZu.length; i++) {// 检验是否建堆成功 if (shuZu[i] -
         * shuZu[2 * i + 2] < 0) { System.out.println(i); } if (shuZu[i] - shuZu[2 * i +
         * 1] < 0) { System.out.println(i); } }
         */
        // System.out.println(Arrays.toString(shuZu));
        for (int i = 0; i < shuZu.length - 1; i++) {
            yiwei(shuZu, shuZu.length - 1 - i);
        }
        // System.out.println(Arrays.toString(shuZu));
        /*
         * for (int i = 1; i < shuZu.length; i++) { if (shuZu[i] - shuZu[i - 1] < 0) {
         * System.out.println(i); } }
         */
        long endTime = System.currentTimeMillis();
        System.out.println("堆排序时间:" + (endTime - stratTime));
    }

    private static void yiwei(int[] shuZu, int endKey) {
        if (endKey == 0) {
            return;
        }
        int top = shuZu[0];
        int endNum = shuZu[endKey];
        int lastYiWeiKey = getYiWeiKey(shuZu, 0, endKey + 1, endNum);
        shuZu[lastYiWeiKey] = shuZu[endKey];
        shuZu[endKey] = top;

        /*
         * for (int i = 1; 2 * i + 2 < endKey + 1; i++) {// 检验是否建堆成功 if (shuZu[i] -
         * shuZu[2 * i + 2] < 0) { System.out.println(i + "--" + shuZu[i] + ":" +
         * shuZu[2 * i + 2]); } if (shuZu[i] - shuZu[2 * i + 1] < 0) {
         * System.out.println(i + "--" + shuZu[i] + ":" + shuZu[2 * i + 1]); } }
         */

        // System.out.println(endKey + "::" + Arrays.toString(shuZu));
    }

    // 此方法不仅是把子节点较大数移到父节点,还判断最后一个数字该去哪
    private static int getYiWeiKey(int[] shuZu, int i, int length, int endNum) {
        int leftKey = 2 * i + 1;
        int rightKey = 2 * i + 2;
        if (leftKey >= length) {
            return i;
        }
        int leftCode = shuZu[leftKey];
        if (rightKey >= length) {
            if (leftCode < endNum) {
                return i;
            }
            shuZu[i] = leftCode;
            return getYiWeiKey(shuZu, leftKey, length, endNum);
        }
        int rightCode = shuZu[rightKey];
        if (rightCode > leftCode) {
            if (rightCode < endNum) {
                return i;
            }
            shuZu[i] = rightCode;
            return getYiWeiKey(shuZu, rightKey, length, endNum);
        } else {
            if (leftCode < endNum) {
                return i;
            }
            shuZu[i] = leftCode;
            return getYiWeiKey(shuZu, leftKey, length, endNum);
        }

    }

    /**
     * @param shuZu
     * @param i
     * @return
     * @author: guzhangyan
     * @version:2018年8月7日 下午8:00:20 建堆
     */
    private static int jianDui(int[] shuZu, int i) {
        int leftKey = 2 * i + 1;
        int rightKey = 2 * i + 2;
        int parentCode = shuZu[i];
        if (leftKey >= shuZu.length) {
            return parentCode;
        }
        int leftCode = jianDui(shuZu, leftKey);
        if (rightKey >= shuZu.length) {
            if (leftCode > parentCode) {
                shuZu[i] = leftCode;
                shuZu[leftKey] = parentCode;
                parentCode = shuZu[i];
                jianDui(shuZu, leftKey);
            }
            return shuZu[i];
        }
        int rightCode = jianDui(shuZu, rightKey);
        if (rightCode > parentCode && rightCode >= leftCode) {
            shuZu[i] = rightCode;
            shuZu[rightKey] = parentCode;
            jianDui(shuZu, rightKey);
        } else if (leftCode > parentCode) {
            shuZu[i] = leftCode;
            shuZu[leftKey] = parentCode;
            parentCode = shuZu[i];
            jianDui(shuZu, leftKey);
        }
        return shuZu[i];

    }

}

一亿条数据的时间为17.620秒。建堆时间为7.043秒。

猜你喜欢

转载自blog.csdn.net/qq_33321609/article/details/81487554
今日推荐