【排序】堆排序

以从小到大的顺序进行说明。

堆排序

堆排序是指利用堆(大根堆、小根堆)进行排序。

原理:大根堆的根节点的值要比孩子节点的值大,从而就可以每次调整都少调整一个最后一个叶子结点,那么就可以将最大值源源不断地向后放

  • 主要用到的还是向下调整算法,不过每次调整的时候会将调整的范围缩小一个
  • 在进行堆排序之前需要进行建大根堆(每次将大值移到最后才能实现从小到大
  • 建完堆后就可以循环往复地去进行向下调整建堆

时间复杂度

O(n*log2n)

建堆的复杂度是O(n)
向下调整的算法复杂度是O(nlog2n)
最终复杂度是:O(n) + O(n
log2n),可以将O(n)省略

空间复杂度

O(1)

无额外空间消耗

稳定性

不稳定

代码

public void heapSort(int[] array) {
        // 先建大根堆
        createBigHeap(array);
        int end = array.length-1;
        while (end > 0) {
            // 交换第一个和最后一个
            swap(array, 0, end);
            siftDown(array,0, end);
            end--;
        }
    }

    private void createBigHeap(int[] array) {
        // 找到最后一个根节点后向上开始向下调整
        for (int parent = (array.length - 1 - 1) / 2; parent >= 0; parent--) {
            siftDown(array, parent, array.length);
        }
    }

    /**
     * 向下调整,从小到大需要建大根堆
     * @param array
     * @param parent
     */
    private void siftDown(int[] array, int parent, int end){
        // 左孩子
        int child = 2 * parent + 1;
        while (child < end) {
            // 如果右孩子存在,并且右孩子的值大于左孩子的值,将child调整为右孩子的下标
            if (child + 1 < end && array[child + 1] > array[child]) {
                child = 2 * parent + 2;
            }
            // 进行交换
            if (array[parent] < array[child]) {
                swap(array, parent, child);
                // 向下调整
                parent = child;
                child = 2 * parent + 1;
            } else {
                // 已经完成了剩余的建堆
                break;
            }
        }
    }
    private void swap(int[] array, int i, int j) {
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值