堆排序及其堆结构

这里以大根堆为例,着重关注是什么堆化的、以及在堆中插入一个新数后如何进行调堆的操作

代码:

import java.util.Random;

/**
 * 堆排序
 */
public class heap {

    /**
     * 堆排序
     */
    public static void heapsort(int[] arr){
        if(arr ==null||arr.length<2){
            return;
        }
        //相当于将数组变为大根堆
        for (int i=0;i<arr.length;i++){
            heapInsert(arr,i);
        }
        int heapsize=arr.length;
        //第一个数和最后一个数进行交换
        swap(arr,0,--heapsize);
        while (heapsize>0){
            heapify(arr,0,heapsize);
            swap(arr,0,--heapsize);
        }

    }

    /**
     * 交换
     * @param a
     * @param b
     */
    public static void swap(int[] arr,int a,int b){
        int temp=arr[a];
        arr[a]=arr[b];
        arr[b]=temp;
    }
    /**
     * 大根堆调堆(从当前节点向上找父节点依次比较)
     * @param arr
     * @param index
     */
    public static void heapInsert(int[] arr,int index){
        while (arr[index]>arr[(index-1)/2]){
            swap(arr,index,(index-1)/2);
            index = (index-1)/2;
        }
    }

    /**
     * 某个数在index位置时判断是否往下移动
     * heapify(堆化)
     * @param arr 数组
     * @param index 父节点
     * @param heapsize 堆的大小
     */
    public static void heapify(int[] arr,int index,int heapsize){
        //左孩子下标
        int left = index*2+1;
        //如果有左孩子(为什么是左孩子? 答: 那是因为堆是一个完全二叉树,看左孩子是否存在就等于判断下面是否还要孩子)
        while (left<heapsize){
            //比较两个孩子中最大的一个
            int max = left + 1 < heapsize && arr[left+1]>arr[left] ? left+1 : left;
            //比较父亲和最大的孩子之间谁大,如果孩子大则交换
            max = arr[max] > arr[index] ? max : index;
            //说明 父亲节点加上两个孩子节点在内的一个堆里面,父亲就是最大的。所以不需要再进行后续判断
            if(max == index){
                break;
            }
            //最大的一个孩子节点和父节点交换
            swap(arr,max,index);
            //换完父节点之后继续,来到父节点位置
            index = max;
            //新的左孩子下标
            left = index*2+1;
        }
    }

    public static void main(String[] args) {
        int[] arr=new int[10];
        Random random=new Random();
        for(int i=0;i<10;i++){
            arr[i]= random.nextInt(10);
        }
        System.out.println("堆排序前的数为:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print("  "+arr[i]);
        }
        heapsort(arr);
        System.out.println("\n++++++++++++++++++++++++++++++++++++++++");
        System.out.println("堆排序后的数为:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print("  "+arr[i]);
        }
    }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值