数据结构排序算法堆排序代码实现升序、降序排序

package Tree;

import java.util.Arrays;

public class HeapSort {
    public static void main(String[] args) {
        int [] arr = {4,6,8,5,9,-1,10,-999};
        //测试升序
        //heapSort(arr);
        // System.out.println(Arrays.toString(arr));

        //测试降序
        heapSortMaxDown(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static void heapSort(int [] arr){
        int length = arr.length;
        int temp = 0;

        //第一次调整,从第一个非叶子结点(下标为arr.length / 2 - 1)开始调整
        for(int i = length / 2 - 1; i >= 0; i--){
            adjustHeapMax(arr,i,length);
        }

        for(int j = arr.length - 1; j > 0; j--){
            temp = arr[j];
            arr[j] = arr[0];//把最大值交换到末尾
            arr[0] = temp;
            adjustHeapMax(arr,0,j);//从第二次开始,每次都是从根节点(0)开始调整
        }
    }

    //最大堆(升序),最小堆(降序)
    /**
     *
     * @param arr 排序数组
     * @param i  完成以i 对应的非叶子结点的树调成大顶堆
     * @param length 调整的长度
     */
    //调整成最大堆
    public static void adjustHeapMax(int [] arr, int i, int length){
        int temp = arr[i];

        //2 * i + 1 --> i 结点的左子节点(如果存在), 2 * i + 2 -->i 结点的右子结点的下标(如果存在)
        for(int k = 2 * i + 1; k < length; k = 2 * k + 1){
            if(k + 1 < length && arr[k] < arr[k+1]){//左子节点的值 < 右子结点的值
                k++;
            }
            //判断是否交换
            if(arr[k] > temp){
                arr[i] = arr[k];
                i = k;// i 指向 k 继续循环
            }else {
                break;//说明此子树已经不用调整,因为调整顺序为从左至右,从下至上
            }
        }
        //for 循环结束后,已经将以 i 为父结点的树的最大值,放在了最顶(父结点),局部最大
        arr[i] = temp;//将temp放到被调整的位置
    }

    //降序排序
    public static void heapSortMaxDown(int [] arr){
        int temp = 0;
        int length = arr.length;

        for(int i = length / 2 - 1; i >= 0; i--){
            heapAdjustMin(arr,i,length);
        }

        for(int j = arr.length - 1; j > 0; j--){
            temp = arr[j];
            arr[j] = arr[0];//把最小值提到末尾
            arr[0] = temp;
            heapAdjustMin(arr,0,j);
        }

    }

    //调整成最小堆
    public static void heapAdjustMin(int [] arr, int i, int length){
        int temp = arr[i];

        for (int k = 2 * i + 1; k < length; k = k * 2 + 1){
            if(k + 1 < length && arr[k] > arr[k + 1]){
                k++;
            }
            //和父结点比较大小,判断是否需要交换
            if(temp > arr[k]){
                arr[i] = arr[k];
                i = k;
            }else {
                break;
            }
        }

        arr[i] = temp;
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值