Java常用排序算法之堆排序

public class HeapSort {
    static final int SIZE = 10;

    public static void main(String[] args) {
        int arr[] = new int[SIZE];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) (Math.random() * 100);
        }
        System.out.println("排序前的数组:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
        heapSort(arr, SIZE);
        System.out.println("堆排序后的数组:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    private static void heapSort(int arr[], int n) {
        int i, j, h, k;
        int t;//定义交换数组是的中间过渡变量

        //输出原数据构成的堆
        for (i = n / 2 - 1; i >= 0; i--) {
            while (2 * i + 1 < n) {// 第i个结点有子树(至少有左子树)
                j = 2 * i + 1;// j为i结点左子树索引
                if ((j + 1) < n) {// 判断第i结点是否有右子树
                    if (arr[j] < arr[j + 1]) {
                        j++;// 如果有右子树并且右子树大于左子树,则比较结点与其右子树,j++即右子树索引
                    }
                } // 如果没有右子树或者右子树小于等于左子树则比较结点与其左子树大小
                if (arr[i] < arr[j]) {
                    t = arr[i];
                    arr[i] = arr[j];
                    arr[j] = t;
                    i = j;// 由于此时堆被破坏,需要重新调整结点j,将j赋给i
                } else {
                    break;
                }
            }
        }
        System.out.print("原数据构成的堆为:");
        for (h = 0; h < n; h++) {
            System.out.print(" " + arr[h]);
        }
        System.out.println();



        //输出每一步剩下的(i--)个数据构成的堆和已排序的数据
        for (i = n - 1; i > 0; i--) {
            t = arr[0];
            arr[0] = arr[i];// 依次arr[0]与arr[n-1]、arr[n-2]、arr[n-3]...交换
            arr[i] = t;
            k = 0;
            while (2 * k + 1 < i) {// 上面交换后,待排序的数组长度为i,判断第k个结点有子树(至少有左子树)
                                        //从第k=0个结点开始,只比较改变破坏的的部分,不改变未破坏的部分
                j = 2 * k + 1;// 第k个结点左子树索引定义为j
                if ((j + 1) < i) {// 判断是否有右子树
                    if (arr[j] < arr[j + 1]) {
                        j++;// 如果有右子树并且右子树大于左子树,则比较结点与其右子树,j++即右子树索引
                    }
                } // 如果没有右子树或者右子树小于等于左子树则比较结点与其左子树大小
                if (arr[k] < arr[j]) {
                    t = arr[k];
                    arr[k] = arr[j];
                    arr[j] = t;
                    k = j;// 由于此时堆被破坏,需要重新调整结点j,将j赋给k
                } else {
                    break;
                }
            }
            System.out.print("第" + (n - i) + "步排序结果:");
            for (h = 0; h < n; h++) {
                System.out.print(" " + arr[h]);
            }
            System.out.println();
        }
    }
}

输出:

排序前的数组:
87 68 34 70 29 88 83 33 76 29 
原数据构成的堆为: 88 76 87 70 29 34 83 33 68 29
第1步排序结果: 87 76 83 70 29 34 29 33 68 88
第2步排序结果: 83 76 68 70 29 34 29 33 87 88
第3步排序结果: 76 70 68 33 29 34 29 83 87 88
第4步排序结果: 70 33 68 29 29 34 76 83 87 88
第5步排序结果: 68 33 34 29 29 70 76 83 87 88
第6步排序结果: 34 33 29 29 68 70 76 83 87 88
第7步排序结果: 33 29 29 34 68 70 76 83 87 88
第8步排序结果: 29 29 33 34 68 70 76 83 87 88
第9步排序结果: 29 29 33 34 68 70 76 83 87 88
堆排序后的数组:
29 29 33 34 68 70 76 83 87 88 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值