• 从10亿个数据中,取出前1000个最大的数


    采用小顶堆

    public class TopN {
    
        /**
         * 找出数组arr中最大的前n个值,不要求这n个值有序
         */
        public static int[] topN(int[] arr, int n) {
            /**
             * 构建堆积
             */
            int[] list = new int[n];
            System.arraycopy(arr, 0, list, 0, n);
            // 在堆顶的始终是最小的值
            for (int i = 0; i < n; i++) {
                int t = i;
                while (t != 0 && list[parent(t)] > list[t]) {
                    swap(list, t, t = parent(t));
                }
            }
    
            /**
             * 小顶堆
             */
            for (int i = n, len = arr.length; i < len; i++) {
                if (arr[i] >= list[0]) {
                    // 置换栈顶
                    list[0] = arr[i];
                    // 调整栈顶
                    int t = 0;
                    // left(t) < n 防止下标越界
                    while ((left(t) < n && list[t] > list[left(t)]) || (right(t) < n && list[t] > list[right(t)])) {
                        // 比较右节点和左节点值值,把小的节点值和父节点值对调
                        if (right(t) < n && list[right(t)] < list[left(t)]) {
                            swap(list, t, t = right(t));
                        } else {
                            swap(list, t, t = left(t));
                        }
                    }
                }
            }
            return list;
        }
    
        private static void swap(int[] list, int i, int j) {
            int tmp = list[i];
            list[i] = list[j];
            list[j] = tmp;
        }
    
        /**
         * 父节点索引
         */
        private static int parent(int i) {
            return (i - 1) / 2;
        }
    
        /**
         * 左孩子索引
         */
        private static int left(int i) {
            return 2 * i + 1;
        }
    
        /**
         * 右孩子索引
         */
        private static int right(int i) {
            return 2 * i + 2;
        }
    
        public static void main(String[] args) {
            int[] arr = new int[] { 1, 2, 23, 4, 5, 11, 12, 13, 100 };
            System.out.println("原始数组: ");
            System.out.println(Arrays.toString(arr));
            System.out.println("调整后数组: ");
            System.out.println(Arrays.toString(TopN.topN(arr, 3)));
        }
    
    }
  • 相关阅读:
    IIS应用程序池标识(程序池账户)ApplicationPoolIdentify
    笔记二 sql 基础知识
    笔记三 索引讲解
    SqlParameter使用参数错误,提示请求超时或则查询速度过慢
    SVN 常见操作
    Excel 基本操作
    sql server row_number分页排序
    本地部署IIS
    sql中去掉字段的所有空格
    sql取逗号前后数据与批量修改某一字段某一值
  • 原文地址:https://www.cnblogs.com/moris5013/p/11368425.html
Copyright © 2020-2023  润新知