Java堆排序

本文详细介绍了堆排序算法的原理和实现过程。首先,解释了堆的定义,即二叉树中每个节点都大于等于其子节点的有序状态。接着,通过sink方法展示了如何由上至下地维护堆的有序性,该方法通过不断比较并交换节点与其较大子节点来修复堆。最后,给出了完整的堆排序代码实现,包括初始堆的构建和排序阶段。堆排序是一种高效的排序算法,适用于大数据集的处理。
摘要由CSDN通过智能技术生成

复习排序三:堆排序

对于堆排序的简单介绍

堆排序可以分为两个阶段。在堆的构造阶段中,我们将原始数组重新组织为一个有序堆。在排序阶段,我们把堆顶元素(即数组0下标)与未排序数组的最后一个元素交换,然后再调用 sink 方法把未排序数组重新堆有序化。

1.关于堆一些定义

1)当一棵二叉树的每个节点都大于等于它的两个子节点时,它被称为堆有序
2)二叉堆是一组能够用堆有序的完全二叉树排序的元素,并在数组中按照层级存储(算法第四版中的代码是不使用数组第一个元素的,但我的代码中是使用了的)。

2.由上至下堆的有序化的实现

如果堆的有序状态因为某个节点变得比它的两个子节点或者某个子节点更小而被打破,那么我们可以将它与两个子节点中的较大者来比较恢复堆,交换可能会在子节点处继续打破有序状态,因此我们需要不断地用相同的办法来修复,将节点向下移动直到他的子节点比他更小了或是到达了底部。

    public void sink(int[] nums,int i,int len){
        //保存局部堆顶元素
        int temp = nums[i];
        for (int k = 2 * i + 1; k < len;k = k*2+1) {
            //因为数组从0开始,所以二叉堆的左节点为2*i+1
            if(k + 1 < len && nums[k] < nums[k+1]){ //让k下标指向左右节点较大的数
                k += 1;
            }
            if(nums[i] >= nums[k]) break;//break的原因是左右子树都已经是有序堆了
            if(nums[i] < nums[k]){
                nums[i] = nums[k];
                nums[k] = temp;
                i = k;
            }
        }
    }

3.堆排序代码实现

    public static void heapSort(int[] nums){
        for (int i = nums.length/2-1; i > -1; i--) {//由下至上调用sink使整个堆有序
            sink(nums,i,nums.length);
        }
//        System.out.println(Arrays.toString(nums));
        int temp;
        for (int n = nums.length-1;n > 0 ;n--) {
            temp = nums[n];
            nums[n] = nums[0];
            nums[0] = temp;
            sink(nums,0,n);
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值