堆排序

  排序算法中堆排序是比较复杂的一种,因为它利用到了树结构,它是一种选择排序,与普通的选择排序不同,普通的选择是每次遍历数组去选择最大或最小的数,堆排序是利用完全二叉树结构.

堆排序是一种不稳定的排序.时间复杂度为:平均O(nlog2n),最坏 O(nlog2n),最好情况 O(nlog2n),空间复杂度O(1)

这里写图片描述
排序思想:其中每个结点的关键字都不大于其孩子结点的关键字,这样的堆称为小根堆。

其中每个结点的关键字都不小于其孩子结点的关键字,这样的堆称为大根堆。

举例来说,对于n个元素的序列{R0, R1, … , Rn}当且仅当满足下列关系之一时,称之为堆:

(1) Ri <= R2i+1 且 Ri <= R2i+2 (小根堆)

(2) Ri >= R2i+1 且 Ri >= R2i+2 (大根堆)
图片与排序思想参考:静默虚空博客

接下来我们分析算法来进行大根堆的排序算法,就是要保证树当中的每个父节点的值都必须要大于子节点,我们可以先找出有子节点的节点,然后从该节点开始向前遍历所有节点,分别判断节点的左右子节点的值,如果子节点大于父节点,交换该子节点与父节点.这样到根遍历结束,能够发现根节点为最大值,然后将根节点与最后一个节点(广度遍历)交换,然后从倒数第二个节点开始向前遍历,重复此操作.

public static void heapSort(int[] array) {
        for (int i = 0; i < array.length - 1; i++) {
            // 构造堆
            constructHeap(array, array.length - i - 1);
            // 交换根(最大值)与最后一位
            exchange(array, array.length - i - 1);
            print(array, i); // 打印
        }
    }

    // 构造堆
    public static void constructHeap(int[] array, int length) {
        int parent = (length - 1) / 2;
        for (int i = parent; i >= 0; i--) {
            // 肯定存在左孩纸 比较子孩纸与父节点的大小
            int child = i * 2 + 1;
            if (array[child] > array[i]) {
                swap(array, i, child);
            }
            if ((child = i * 2 + 2) <= length) {
                // 存在右孩纸
                if (array[child] > array[i]) {
                    swap(array, i, child);
                }
            }
        }
    }

    public static void exchange(int[] array, int end) {
        int temp = array[0];
        array[0] = array[end];
        array[end] = temp;
    }

    // 打印
    public static void print(int[] array, int index) {
        System.out.print("第 " + index + " 次排序后: ");
        for (int i : array) {
            System.out.print(i + " ");
        }
        System.out.println("\n");
    }

    public static void swap(int[] array, int index1, int index2) {
        int temp = array[index1];
        array[index1] = array[index2];
        array[index2] = temp;
    }

测试:

        int[] array = new int[] { 1, 4, 5, 12, 13, 14, 18 };// 5 5 5 14 14 14 18
        heapSort(array);
第 0 次排序后: 14 1 13 4 12 5 18 

第 1 次排序后: 5 12 13 1 4 14 18 

第 2 次排序后: 4 5 12 1 13 14 18 

第 3 次排序后: 1 4 5 12 13 14 18 

第 4 次排序后: 4 1 5 12 13 14 18 

第 5 次排序后: 1 4 5 12 13 14 18 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值