• Java排序算法 [堆排序]


    package cn.com.dom4j.sort;
    
    import java.util.Arrays;
    
    public class Test2 {
    
        /**
         * 堆排序
         */
        public static <AnyType extends Comparable<? super AnyType>> void heapSort(AnyType[] a) {
    
            // buildHeap
            for (int i = a.length / 2; i >= 0; i--) {
                // 将数组值按初始顺序放入堆中, 从根节点执行下滤操作将构建一个堆
                percolateDown(a, i, a.length);
            }
    
            // deleteMax
            for (int i = a.length - 1; i > 0; i--) {
                // 在构建了一个 max堆后, 将根节点与最后一个元素互换, 同时将堆的大小 -1, 调整位置, 再次实现堆序
                // 这样每互换一次, 最大的元素就会放在堆的后面 (已经从堆中删除, 不属于堆了), 堆后面的元素会保持顺序, 直到堆中只剩一个元素为止
                swap(a, 0, i);
                percolateDown(a, 0, i);
            }
    
        }
    
        /**
         * 下滤操作: 调整某个节点的位置, 以保持堆序
         * @param a 待排序序列
         * @param i 要调整的节点在数组中的索引
         * @param n 堆的大小 (堆中元素个数)
         */
        private static <AnyType extends Comparable<? super AnyType>> void percolateDown(AnyType[] a, int i, int n) {
    
            int child;
            AnyType tmp;
    
            // tmp记录被调整元素的值, i的值随 child不断改变, 直到比较完所有的子节点 (leftChild(i) < n) 为止
            for (tmp = a[i]; leftChild(i) < n; i = child) {
                child = leftChild(i);
                // child == n - 1时, 其左子节点为堆的最后一个元素, 没有右节点, 无须比较
                // 将该节点与其左右节点比较, 记录其中最小的节点的索引
                if (child != n - 1 && a[child].compareTo(a[child + 1]) < 0) {
                    child++;
                }
                // 将需要被调整和节点与其子节点进行比较, 如果小于子节点, 当前节点的值替换为子节点的值 (注意不是交换)
                if (tmp.compareTo(a[child]) < 0) {
                    a[i] = a[child];
                } else {
                    break;
                }
            }
            // 找到合适的位置后, 直接赋值来避免多余的交换操作
            a[i] = tmp;
        }
    
        /**
         * 获取某个节点的左子节点在数组中的索引, 因为是从 0开始的, 所以要 +1
         */
        private static int leftChild(int i) {
            return 2 * i + 1;
        }
    
    
        /**
         * 交换数组中两个元素的位置
         */
        public static <AnyType extends Comparable<? super AnyType>> void swap(AnyType[] arr, int i, int j) {
            if (arr == null || arr.length <= 1 || i == j) {
                return;
            }
    
            AnyType tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }
    }

  • 相关阅读:
    LeetCode Reverse Integer
    LeetCode 3Sum Closest
    LeetCode Remove Duplicates from Sorted Array
    解决git 远程删除分支之后,vscode本地分支列表没有更新问题
    reduce, filter, map, forEach 使用
    ehcarts tooltip 自定义展示. 展示小图例
    vscode插件,代码块,快捷键 入门
    DorisSQL与MySQL函数对照 差异篇
    Doris与mysql语法对照,差异篇
    功能测试报告模板
  • 原文地址:https://www.cnblogs.com/bobo132/p/13950372.html
Copyright © 2020-2023  润新知