逐句解释堆排序

//堆排序1
    private static int heapSize;//声明全局变量,记录堆中有多少元素
    private static Integer[] array;//声明全局变量,存储传来要排序的元素
    
    static void heapSort(Integer[] arr) {
        array = arr;
        //原地建堆
        heapSize = arr.length;
        //从最后一个非叶子节点向上构建最大堆(二叉堆的逻辑结构是一个完全二叉树,最后一个非叶子节点索引=节点数/2-1)
        for (int i = (heapSize >> 1) - 1; i >= 0; i--) {
            siftDown(i);
        }
        //交换---堆顶元素和堆尾元素,直到堆中元素只剩1个
        while (heapSize > 1) {
            Integer tmp = arr[0];//堆顶元素
            heapSize--;
            arr[0] = arr[heapSize];
            arr[heapSize] = tmp;

            //对堆顶元素0位置进行下滤操作,恢复堆的性质
            siftDown(0);

        }
    }

//下滤---自底向上原地建堆
    private static void siftDown(int index) {//传入要下滤的节点
        Integer element = array[index];//获取传入的节点的元素
        int half = heapSize >> 1;//将元素个数减半,判断,传入节点是否是叶子结点
        //以完全二叉树作为逻辑结构, 节点数量减半后的索引位置都是叶子节点
        while (index < half) {//index位置必须非叶子节点
            //获取左孩子节点,不是叶子节点,左节点一定不为空
            int childrenIndex = (index << 1) + 1;
            int child = array[childrenIndex];//获取左孩子元素
            int rightIndex = childrenIndex + 1;//右孩子索引就是左孩子+1
            //判断右孩子索引在数组容量范围内, 右孩子节点大于左孩子节点
            if (rightIndex < heapSize && array[rightIndex]- child > 0) {
                //将childrenIndex指向值更大的孩子
                childrenIndex = rightIndex;
                //将child变为更大的值
                child = array[rightIndex];
            }
            //判断传入元素大于>=孩子节点
            if (element - child >= 0) {
                break;//跳出
            }
            //到这里代表传入元素比孩子节点元素小
            array[index] = child;//就将对应的孩子换到父节点的索引位置
            index = childrenIndex;//再将索引换成原本的孩子节点
        }
        array[index] = element;//索引元素最后在堆中的位置
    }
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值