十大排序之堆排序


前言

堆包括

  • 大根堆:父节点的值都大于其左右孩子的值
  • 小根堆: 父节点的值都小于其左右孩子的值

提示:以下是本篇文章正文内容,下面案例可供参考

一、基本思想

按照堆的定义构建起一个堆,那么每次就可以确定一个最大值或最小值(根上),那么将这个值放入数组最后一位,即可排好了一位元素。后续以此缩减范围递归处理。

二、性能分析

  • 空间复杂度O(1)
  • 时间复杂度O(nlog2n)
  • 不稳定排序算法

三、实现代码

调用排序方法:

   public void  HeapSort(){
        System.out.println(Arrays.toString(arr));
//        初始化堆化
        MaxHeap(arr,arr.length);
        for (int i = arr.length-1; i >=0 ; i--) {
//        将第一个元素(最大的这一个)交换到数组末尾
            SwapArraysDoucment.swap(arr,0,i);
//         将交换后的元素继续堆化
            MaxHeapFixDown(arr,0,i);
        }
        System.out.println(Arrays.toString(arr));
    }

初始化堆:

    public void MaxHeap(int arr [],int len){
//        从len/2+1开始调整 是最后一个非叶子节点 叶子节点可视为已经堆化
        for (int i = len/2+1; i >=0; i--) {
//            对该子树进行堆化
            MaxHeapFixDown(arr,i,len);
        }
    }

小顶堆化代码:

    private void MinHeapFixDown(int[] arr, int cur_root, int len) {
        int left = cur_root*2+1;
        int right = cur_root*2+2;
//        找到左右孩子 左右孩子可能会有不同的情况
//        如果该结点是叶子 那么无需处理 也就是递归出口
        if(left>=len){
            return;
        }
//        初始化最小孩子下标为 左孩子
        int min  =left;
//        有做孩子,没有右孩子的情况 最小孩子下表也初始化为左孩子 
        if(right>=len){
            min = left;
        }else {//左右孩子都有的情况
//        对比左右孩子 找到最小的一个
            if(arr[right]<arr[left]){
//        确定了最小的一个孩子
                min = right;
            }
        }
//        如果最小孩子的值比父节点还要小 那么交换
        if(arr[cur_root]>arr[min]){
//        交换根节点的元素和最小的一个的孩子的位置
            SwapArraysDoucment.swap(arr,cur_root,min);
//         并且递归处理最小一个孩子的位置 
            MinHeapFixDown(arr,min,len);//min的下标是不断变化的 为递归增量
        }
    }

大顶堆化代码同理:

private void MaxHeapFixDown(int[] arr, int cur_root, int len) {
//        找到左右孩子 左右孩子可能会有不同的情况
        int left = cur_root*2+1;
        int right = cur_root*2+2;
//        没有孩子
        if(left>=len){
            return;
        }
        int max  =left;
        if(right>=len){
//        没有右孩子
            max = left;
        }else {
//        对比左右孩子 找到最大的一个
            if(arr[right]>arr[left]){
//        确定了最大的一个孩子
                max = right;
            }
        }
//        交换根节点的元素和最小的一个的孩子的位置
        if(arr[cur_root]<arr[max]){
            SwapArraysDoucment.swap(arr,cur_root,max);
//         并且递归处理最小一个孩子的位置
            MaxHeapFixDown(arr,max,len);
        }
    }

总结

本文记录了复习堆排序的一些过程。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值