【七、堆排序】

堆排序:
1.先创建好大根堆
2.每一趟将堆顶元素加入有序子序列【即将堆顶元素与待排序序列中的最后一个元素交换】
3.将待排序元素序列再次调整为大根堆

图解:

书上代码是从i=1存储元素,相当于在i=4(i=len/2)时调整
下处代码是从i=0存储元素,所以在i=3(i=len/2-1)时调整

在这里插入图片描述

public class 堆排序 {
    public static void main(String[] args) {
//        int nums[]={1,3,4,5,2};
        int nums[]={49,38,65,97,76,13,27,49,55,04};
        sort(nums);
        System.out.println(Arrays.toString(nums));
    }
    static void sort(int nums[]){
        int len = nums.length;
        BuildMaxHeap(nums);     //建立初始堆
        for (int i=len-1;i>0;i--){
            swap(nums,i,0); //将堆顶元素输出(和堆底元素交换)
            HeadAdjust(nums,0,i);   //重新调整为新堆
        }
    }

    //建立大根堆
    static void BuildMaxHeap(int nums[]){
        int len = nums.length;
        for(int i=len/2-1;i>=0;i--){
            HeadAdjust(nums,i,nums.length); //反复调整堆,使其成为大根堆
        }
    }

    static void HeadAdjust(int[] nums, int k, int len) {
        int temp=nums[k];       //暂存子树的根节点
        //i=i*2+1找到 所调整结点的左子树
        //i=i*2+1是确保调整后的 “子树”  也能保持大根堆状态
        //如果调整后,“调整结点所在子树” 不能保证大根堆,i=i*2+1发挥作用,重新调整子树
        for (int i =2*k+1;i<len;i=i*2+1){
            if (i+1<len&&nums[i]<nums[i+1]) //比较孩子结点
                i++;                        //取key较大的子结点的下标
            if (temp>=nums[i]) break;       //筛选结束
            else{
                nums[k]=nums[i];            //将nums[i]调整到双亲结点上
                k=i;                        //修改key值,以便能够继续向下筛选
            }
        }
        nums[k]=temp;                       //被筛选结点的值放入最终位置
    }

    static void swap(int nums[],int a,int b){
        int temp = nums[a];
        nums[a]=nums[b];
        nums[b]=temp;
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值