堆排序

把一个数组 构建为大顶堆的过程  

 

根据完全二叉树的性质  计算出来 某个节点 父节点的index   左孩子的index 右孩子的index  

 

/**
 * 堆排序
 *
 */
public class MyHeapSort extends App {

    /**
     * 把数组构建为大顶堆
     */
    private static void buildMaxHeap(int[] arr, int len) {
        //找出最后一个节点 的索引值
        int lastnodeIndex = len-1 ;

        //找出最后一个节点 的父亲节点的索引值   (依据完全二叉树的性质 )
        int startparent = (lastnodeIndex-1)/2;

        //依次堆化
        for (int i = startparent; i >= 0; i--) {
            heapify(arr,i,len);
        }
    }

    public static void main(String[] args) {
        int[] array = {6,7,88,3,5,77,112,999,3453,90,100,2,1} ;

        //先把当前数组 构建为大顶堆  那么他的第一个元素  一定是最大的
        //下面的 swap(array,i,0);  是把第一个元素 和最后一个元素 进行交换
        //  那么最大的元素就排好了
        buildMaxHeap(array,array.length);

        //每走一趟  本次最大的元素 就放到了最后的位置
        for(int i=array.length-1;i>=0;i--){
            //把最大的元素 和 最后位置的元素进行交换
            swap(array,i,0);
            //从index为0 的位置 重新堆化
            heapify(array,0,i);
        }

        logger.info(Arrays.toString(array));
    }

    /**
     *
     * 把数组arr 的第i个元素  和 第j个元素 交换
     *
     */
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    /**
     * 堆化函数
     * @param arr  数组
     * @param i    从当前index开始 进行堆化
     * @param len  数组的长度
     */
    private static void heapify(int[] arr, int i, int len) {
        //当前index 左孩子的索引值
        int left = 2 * i + 1;
        //当前index  右孩子的索引值
        int right = 2 * i + 2;
        int largest = i;

        //如果左孩子 大于 根节点  交换
        if (left < len && arr[left] > arr[largest]) {
            largest = left;
        }
        //如果右孩子 大于 根节点  交换
        if (right < len && arr[right] > arr[largest]) {
            largest = right;
        }
        //说明 当前节点 不符合大顶堆
        if (largest != i) {
            //进行交换
            swap(arr, i, largest);
            //从当前节点  重新进行堆化
            heapify(arr, largest, len);
        }
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值