堆排序

博客介绍了堆排序相关内容,包括向上调整、向下调整(堆化)、建堆等操作。在Java中实现堆排序,需先将数组建成大堆,把最大数换到末尾,再对剩余数堆化,循环操作以实现从小到大排序,最后还提及了测试。

向上调整、向下调整(堆化)
建堆

排序 结果从小到大排序
堆排序: 首先你要先将一个数组 array建立成一个大堆,然后每次将最大的数换到最后一个数的位置,就是array[0]位置的数与最后一个数互换位置;接着再将(不包括那个最大数的)剩下的数进行堆化,使其再次成为一个大堆,再接着将最大的数换下来;以此循环。

//**堆排序**

    private static void heapSort(int[] array){

        //首先需要创建一个大堆
        createHeap(array);
        for (int i= 0; i < array.length; i++) {
            //然后将最大的数array[0]与最后一个数(不包括之前换下来的最大的那个数)互换位置
            int t=array[0];
            array[0]=array[array.length-1-i];
            array[array.length-1-i]=t;
            //不包括最后一个换下来的最大的一个数,再进行堆化
            heapify(array,0,array.length-1-i);//进行堆化的长度变了,就是堆化时,不包括之前换下来的最大的数了
        }
    }
    
    /**/建堆**
    private static void createHeap(int[] array){
        //最后一个非叶子结点
        int index=(array.length-1-1)/2;
        while(index>=0){
            heapify(array,index,array.length);
            index--;
        }
    }


    //堆化为大堆
    //**堆化**(向下调整)  前提是 只有一个地方不满足堆的性质,其他位置都满足堆的性质
    private static void heapify(int[] array,int index,int size){
        //看该节点是不是叶子结点
        //其左孩子节点下标
        int max=2*index+1;
        //如果左孩子下标超过数组长度,则该结点是叶子结点
        if(max>=size){
            return;
        }
        //找出孩子结点中值最大的结点下标
        if(max+1<size&&array[max+1]>array[max]){
            max=max+1;
        }

        //比较该根结点与最大的孩子结点的大小,如果孩子结点大,则换位置
        if(array[index]<array[max]){
            int t=array[index];
            array[index]=array[max];
            array[max]=t;
            //换完之后,在该index结点处满足堆的性质了,
            //但是在max位置,其与它的孩子结点不一定满足堆的性质了,在max位置继续进行堆化
            heapify(array,max,size);

        }

    }

测试

 public static void main(String[] args) {

        //int[] array=new int[]{1,2,3,4,5,6,7,8,9,10};
       int[] array=new int[]{2,5,8,9,10,3,16,6,7,14};
        //createHeap(array);
        heapSort(array);
        System.out.println(Arrays.toString(array));
    }

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值