堆排序算法

堆排序_HeapSort

HEAPSORT:理解的不透彻,还要写

1.堆排序算法基本思想

  • Grammar Thoughts:
    *将待排序的序列构造成一个大顶堆

  • 整个序列的最大值就是堆顶的根节点,将其去对数组的末尾元素交换,然后将剩余的(n-1)个系列重新构造成一个堆,这样就会得到n个元素中的次最大值,如此反复执行费

  • ,就可以得到一个有序序列

  • :完全二叉树

2.代码实现_(Java)

package SevenSorts;

/**
 * Grammar Thoughts:
 *将待排序的序列构造成一个大顶堆
 * 整个序列的最大值就是堆顶的根节点,将其去对数组的末尾元素交换,然后将剩余的(n-1)个系列重新构造成一个堆,这样就会得到n个元素中的次最大值,如此反复执行费
 * ,就可以得到一个有序序列
 *
 * 堆:完全二叉树
 */
public class HeapSort {
    //==========================================================================
    //将序列改成大顶堆
    public  static void heapSort(int[] arr){
        if(arr==null||arr.length==1) return;
        //数组转换为大顶堆
        buildArrToHeap(arr);
    }
    //构造大顶堆(可以是小顶堆)--看你自己怎么去实现
    private static void buildArrToHeap(int[] arr) {
        if(arr==null||arr.length==1){
            return;
        }
        //递推公式就是:int root=2*i,int left=2*i+1; int right=2*i+2;
        int cursor=arr.length/2;
        for(int i=cursor;i>=0;i++){
            //构造大顶堆
            buildMaxHeap(arr,arr.length,i);
        }
    }

    private static void buildMaxHeap(int[] arr, int heapSize, int index) {
        //左右子节点
        int left=index*2+1;
        int right=index*2+2;
        //当前父节点index暂定为最大值(哨兵作用)
        int maxVal=index;
        //将左右子节点与父节点比较,如果子节点大于父节点交换(左右比较的顺序不能够改变)
        if(left<heapSize&&arr[left]>arr[maxVal]){
            maxVal=left;
        }
        if(right<heapSize&&arr[right]>arr[maxVal]){
            maxVal=right;
        }
        //如果不相等说明有子节点比父节点打的,交换位置
        if(maxVal!=index){
            swap(arr,maxVal,index);
        }
        //还哦需要进行最后一个判断:看看子节点是否打破了最大堆的性质(子节点是够都比父节点小),
        buildMaxHeap(arr,arr.length,index);
    }

    private static void swap(int[] arr, int i, int j) {
        arr[i]^=arr[j];
        arr[j]^=arr[i];
        arr[i]^=arr[j];
    }
    //==========================================================================
    //大顶堆优化实现算法
    //==========================================================================
    //初始化数组和构造器
    private int[] arr;
    public HeapSort(int[] arr){
        this.arr=arr;
    }
    //堆排序的主要入口方法
    public void  sort(){
        /**
         * 1.数组堆化
         * 2.beginIndex=第一个叶子结点
         *从第一个非叶子节点开始即可。无需从最后一个叶子节点开始。
         **  叶子节点可以看作已符合堆要求的节点,根节点就是它自己且自己以下值为最大
         */
        int len=arr.length-1;
        int beginIndex=(len-1)>>1;
        for(int i=beginIndex;i>=0;i--){
            maxHeapify(i,len);
        }
        for (int j = len; j > 0 ; j--) {
           swap_2(0,j);
            maxHeapify(0,j-1);
        }
    }

    private void swap_2(int i, int j) {
        i=i^j;
        j=i^j;
        i=i^j;
    }

    //堆堆化数据排序
    private void maxHeapify(int index, int len) {
        //左节点的索引
       int li=(index<<1)+1;
        int ri=li+1;
        int cMax=li;
        if(li>len) return;
        if(ri<=len&&arr[ri]>arr[li]){
            cMax=ri;
        }
        if(arr[cMax]>arr[index]){
            swap_2(cMax,index);
        }
        maxHeapify(cMax,len);


    }

    //调整索引为index出的数据


}

参考链接:堆排序算法详解

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值