(七)堆排序

堆排序的基本思想是:将待排序序列构造成一个大根堆或则小根堆,此时,整个序列的最大值或者最小值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值或者最小值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次大值或次小值。如此反复执行,便能得到一个有序序列了(升序就选大根堆,降序选小根堆)

步骤:1、构造初始堆。将给定无序序列构造成一个大顶堆(升序采用大顶堆,降序采用小顶堆)。

           2、将堆顶元素与末尾元素进行交换,使末尾元素最大或者最小。然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。注意理解:交互后的队尾元素 不在参与下次堆调整。

实现代码如下:

public static void heapSortAlgorithm(int[] arr){
        if(null==arr||arr.length<2) return;
        //构建大根堆或小根堆 依据升序或降序需求自己定:升序就大根堆
        //从最后一个非叶子节点开始n=arr.length; 最后一个叶子节点位置pos=n/2-1;
        int len=arr.length;
        int pos=len/2-1;
        for(int i=pos;i>=0;i--){
            adjustHeap(arr,i,len);
        }
        //调整堆 并 交换堆顶元素与末尾元素 以完成排序
        for(int i=len-1;i>=0;i--){
            swap(arr,0,i);
            adjustHeap(arr,0,i);//此处选取i=是去除调整后的最后一个叶子的 因为已经最大 调整时不需要此数据了
        }
    }

    private static void adjustHeap(int[] arr, int pos, int len) {
        int temp=arr[pos];//先记录当前非叶子节点值
        int leafPos=pos*2+1;//当前非叶子节点的第一个叶子节点下标
        for(int i=leafPos;i<len;i=i*2+1){
            if(i+1<len &&arr[i]<arr[i+1]){//如果左边叶子小于右边 则选取右边的
                i++;
            }
            if(arr[i]>temp){
                arr[pos]=arr[i];
                pos=i;//同时修改记录当前非叶子节点变成了比他大的叶子节点
            }else{
                break;
            }
        }
        arr[pos] = temp;//将temp值放到最终的位置
    }

堆排序是一种选择排序,整体主要由构建初始堆、堆顶元素和末尾元素交换并重建堆组成。

堆排序时间复杂度:O(nlogn)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值