【排序算法】之堆排序

堆排序的基本思想是:

具体可看视频演示:堆排序

java 复制代码
- 1、将带排序的序列构造成一个大(小)顶堆,根据大顶堆的性质,当前堆的根节点(堆顶)就是序列中最大的元素;
		buildHeap();
- 2、将堆顶元素和最后一个元素交换交换一次,i--一次,然后将剩下的节点重新构造成一个大顶堆;
		swap() + buildHeap()
- 3、重复步骤2,如此反复,从第一次构建大顶堆开始,每一次构建,我们都能获得一个序列的最大值,然后把它放到大顶堆的尾部。最后,就得到一个有序的序列了。
		heapSort();
代码演示
java 复制代码
/**
 * 堆排序 对简单选择排序的优化
 */
public class HeapSort {
    //堆排序
    public static void heapSort(int[] arr) {
        if (arr == null || arr.length == 0) {
            return;
        }
        int len = arr.length;
        //1.构件大顶堆,把数组变成一个大顶堆结构的数组;
        //要知道数组的长度
        buildHeap(arr, len);
        //2.交换堆顶元素与末尾元素 剩下的元素重新构成一个大顶堆
        for (int i = len - 1; i >= 0; i--) { //每交换一次末位位置要-1
            //4.
            swap(arr, 0, i);
            len--;
            //每次调整的时候默认len-1;因为每次最后位置的数就是我们所求得最大的
            heapify(arr, 0, len);
        }
    }

    //3.heapify真正用来调整大顶堆的方法
    /**
     * @param arr 待整理的数组
     * @param i   每次整理时候,当前非叶子节点的位置
     * @param len   每次整理数组时,节点的个数
     */
    private static void heapify(int[] arr, int i, int len) {
        if (i>=len){
            return;
        }
        //给了一个非叶子节点i的位置 我们首先找到它的两个孩子
        int left = 2 * i + 1;
        int right = 2 * i + 2;
        int max = i;//假设父节点i是最大值的位置
        //下面进行判断找到最大值所在的节点位置 同时要保证节点不会越界
        if (left < len && arr[left] > arr[max]) {
            max = left;
        }
        if (right < len && arr[right] > arr[max]) {
            max = right;
        }
        //找出最大值后就进行交换
        if (max!=i){
            // 如果最大值位置不是当前非叶子节点的位置,那么就把当前节点和最大值的子节点值互换
            swap(arr, i, max);
            // 因为互换之后,子节点的值变了,该子节点可能也有自己的子节点,仍需要再次调整。
            heapify(arr, max,len);
        }
    }
    //1.构造大顶堆
    private static void buildHeap(int[] arr) {
        // 从最后一个非叶节点开始向前遍历,调整节点,使整个数组成为大顶堆
       //数组的长度/2 - 1 就是:第一个非零节点的位置
        int n=arr.length;
        for (int i = n / 2 - 1; i >= 0; i--) {
            //3.
            heapify(arr, i, n);
        }

    }
    //4.交换元素
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void main(String[] args) {
        int[] arr={23,45,1,5,67,88,99,9,2,3};
        heapSort(arr);
        for (int res : arr) {
            System.out.print(res+" ");
        }
    }
}
相关推荐
卡尔特斯3 小时前
Android Kotlin 项目代理配置【详细步骤(可选)】
android·java·kotlin
白鲸开源3 小时前
Ubuntu 22 下 DolphinScheduler 3.x 伪集群部署实录
java·ubuntu·开源
ytadpole3 小时前
Java 25 新特性 更简洁、更高效、更现代
java·后端
纪莫4 小时前
A公司一面:类加载的过程是怎么样的? 双亲委派的优点和缺点? 产生fullGC的情况有哪些? spring的动态代理有哪些?区别是什么? 如何排查CPU使用率过高?
java·java面试⑧股
JavaGuide5 小时前
JDK 25(长期支持版) 发布,新特性解读!
java·后端
用户3721574261355 小时前
Java 轻松批量替换 Word 文档文字内容
java
白鲸开源5 小时前
教你数分钟内创建并运行一个 DolphinScheduler Workflow!
java
CoovallyAIHub5 小时前
中科大DSAI Lab团队多篇论文入选ICCV 2025,推动三维视觉与泛化感知技术突破
深度学习·算法·计算机视觉
Java中文社群5 小时前
有点意思!Java8后最有用新特性排行榜!
java·后端·面试
代码匠心5 小时前
从零开始学Flink:数据源
java·大数据·后端·flink