堆排序算法代码实现

上代码:

package com.liu.pro;

import java.util.Arrays;

public class heapSort {
    public static void main(String[] args) {
        int[] arr = {9, 8, 5, 6, 2, 7, 1, 3, 4};
        sort(arr);
        System.out.println("堆排序算法");
        System.out.println(Arrays.toString(arr));
    }

    public static void sort(int[] arr) {
        int temp = 0;
//分堆  i从非叶子节点(公式:2*n/2-1个)的最大数开始,往前遍历,分堆
        for (int i = arr.length / 2 - 1; i >= 0; i--) {
//          分堆
            adjust(arr, i, arr.length);
        }
//调整排序,需要调整arr.length轮,从数组的最后下标开始调整
        for (int j = arr.length - 1; j >= 0; j--) {
//          值交换
            temp = arr[j];
            arr[j] = arr[0];
            arr[0] = temp;
//          从索引为0开始进行调整,调用函数
            adjust(arr, 0, j);
        }
    }
    /**
     * 调整数组的方法(将其调整为大顶堆或者小顶堆)
     *
     * @param arr    需要调整的数组
     * @param i      非叶子节点
     * @param length 需要调整的数组长度
     */
    public static void adjust(int[] arr, int i, int length) {
//      定义一个temp来存储arr[i],因为后面可能回替换arr[i]
        int temp = arr[i];
//      从当前的非叶子结点的左右孩子结点进行比较,找到最大值,并赋值给a[i]
        for (int j = 2 * i + 1; j < length; j = 2 * j + 1) {
//          j + 1 < length限定不能超过数组的长度,即小于等于length-1
//          arr[j] < arr[j + 1]左右孩子比较
            if (j + 1 < length && arr[j] < arr[j + 1]) {
//              如果满足条件,则更新j索引
//              不更新为左,更新为右,并且下个循环继续寻找
                j++;
            }
//          如果temp的值比左右两边的孩子数值都小,则替换
            if (temp < arr[j]) {
//              arr[i]的值进行了改变,赋值为三个中的最大值,此时的i为非叶子结点
                arr[i] = arr[j];
//              下标一同替换
                i = j;
            } else {
//              不需要进行调整,则直接退出循环,则程序将不会往下走
                break;
            }
            arr[i] = temp;
        }
    }
}

测试结果:

 

posted @ 2022-07-18 22:45  努力学习の小白  阅读(52)  评论(0编辑  收藏  举报
Live2D