堆排序原理与Java代码实现

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


堆排序原理

  1. 推排序:需要先将数组转换为大顶推。
  2. 大顶推:规范是 arr[k] 大于 arr[2k + 1] 和 arr[2k +2],其中k的取值范围0…(arr.length/2 -1)
  3. 得到大顶推之后, 就选取arr[0]的值和最后一个值替换,使得最后一个值最大。数组长度-1,并调整堆顶即可(因只有推顶不符合大顶推规范)。
    每次循环第3步之后,直到数组长度为1为止。

Java代码实现

代码如下:

package com.study.algorithm;

import java.util.Arrays;

public class HeapSort {
    public static void main(String[] args){
        int[] arr = {10,9,2,12,30,1,5};
        sort(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static void sort(int[] arr){

        int n = arr.length/2 - 1;
        //推排序,从下到上, 从左到右
        for(int i = n; i >=0; i--){
            adjustHeap(arr,i,arr.length);
        }
        //经过上述排序, 已经完成大顶推的排序
        //确保了 arr[k] > arr[2*k + 1] 和  arr[2*k + 2]
        int tmp = 0;
        //推排序的每次选取大顶推的首位与未尾值想替换, 实现每次排序在末尾的值在本次是最大的
        //排出掉已排序的未尾即(i--),并对推进行重新调整,已符合大顶推规范
        for(int i = arr.length - 1; i > 0; i--){
            tmp = arr[i];
            arr[i] = arr[0];
            arr[0] = tmp;
            //经过替换后,只有顶部不符合大顶推规范,其他不为是符合大顶推规范的
            //在调整的时候,调整顶部位置即可
            adjustHeap(arr,0,i);

        }

    }
    /**
     * 大顶推:规范 arr[k] > arr[2*k + 1] 和 arr[2*k +2]
     * 调整大顶堆
     * @param arr
     * @param i 调整位置
     * @param length  需要调整数组的长度
     */
    public static void adjustHeap(int[] arr, int i, int length){
        int tmp = arr[i];
        for(int k = (2*i + 1); k < length; k = (k*2 +1)){
            //获取左右子树的最大值索引
            if((k + 1) < length && arr[k] < arr[k+1]){
                k++;
            }
            //如果子树值大于父节点则替换
            if(arr[k] > tmp){
                arr[i] = arr[k];
                i = k;
            }else{
                //否则退出循环,因在调整堆的时候是从下到上,从左到又的
                //保证了k以下的堆是符合大顶推排序规范的
                break;
            }
        }
        arr[i] = tmp;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值