美文网首页
从100w个数中找到前10个最小的,并排序

从100w个数中找到前10个最小的,并排序

作者: chanyi | 来源:发表于2020-08-26 11:44 被阅读0次

    此类问题可以总结为从n(很大)个数中找到m(很小)个最大或最小的数
    此类问题的方法有如下几种
    1、堆排序
    2、位图排序

    1、堆排序

    如果是找最大数,则从n中选择m个数,建立容量为m的大顶堆,然后剩下的数依次遍历,和堆中的数作比较,大的插入,小的跳过。
    此种方法的计算复杂度为n*log(m)。
    具体代码(这里的小顶堆使用java的优先队列PriorityQueue实现

    private static final int nCount = 10;
      private static final int mCount = 5;
      //实现在n个数中找到最大的前m个数
      public static void main(String[] args) {
        int[] n = init_n();
        Queue<Integer> minQueue = init_big_top_heap(mCount,n);
        for (int i = mCount; i < n.length; i++) {
          minQueue = compare(n[i],minQueue);
        }
        //打印最终结果
        System.out.println("");
        System.out.println("result:");
        Iterator iterator = minQueue.iterator();
        while(iterator.hasNext()){
          System.out.print(iterator.next()+",");
        }
      }
    
      //初始化大数组
      public static int[] init_n(){
        //建立一个容量为100w的数组
        int[] n = new int[nCount];
        Random random = new Random();
        for (int i = 0; i < nCount ; i++) {
          n[i] = random.nextInt(128);
        }
        //
        System.out.println("打印初始化数组:");
        for (int i = 0; i < n.length; i++) {
          System.out.print(n[i]+",");
        }
        return n;
      }
    
      //初始化小顶堆
      public static Queue init_big_top_heap(int mCount,int[] mArr){
        Queue<Integer> minQueue = new PriorityQueue<>();
        for (int i = 0; i < mCount; i++) {
          minQueue.add(mArr[i]);
        }
        return minQueue;
      }
    
      //数与堆顶元素比较,如果大则插入,小则跳过
      public static Queue<Integer> compare(int num,Queue<Integer> minQueue){
        if(num>minQueue.peek()){
          minQueue.poll();
          minQueue.add(num);
        }
        return minQueue;
      }
    

    2、位图排序

    思路是:遍历数组中所有元素,找到最大值,然后建立一个以最大值为容量的byte数组用来存放0,1。再次遍历数组,将数组中的元素i对应的byte[i]的值设置为1。得到byte数组之后,从最大值到0开始遍历,如果遍历到的数j对应的byte[j]==1,则放入结果集中。直至结果集满或遍历结束
    (需要注意的是,这里没有考虑数据重复的情况)
    具体代码(代码是在n个数组中找出最大的m个数

    private static final int nCount = 10;
      private static final int mCount = 5;
    
      private static int[]  initArr(){
        int n[] = new int[nCount];
        Random random = new Random();
        for (int i = 0; i < nCount; i++) {
          n[i] = random.nextInt(128);
        }
        System.out.println("打印初始化数组:");
        for (int i = 0; i < n.length; i++) {
          System.out.print(n[i]+",");
        }
        return n;
      }
    
      public static int[] getTop(int[] inputArray) {
        int maxValue = Integer.MIN_VALUE;
        //找到数组中的最大值
        for (int i = 0; i < inputArray.length; ++i) {
          if (maxValue < inputArray[i]) {
            maxValue = inputArray[i];
          }
        }
        System.out.println("maxValue:"+maxValue);
        //建立位图
        byte[] bitmap = new byte[maxValue + 1];
        for (int i = 0; i < inputArray.length; ++i) {
          int value = inputArray[i];
          bitmap[value] = 1;
        }
        int[] result = new int[mCount];
        int index = 0;
        //从最大值遍历到0,如果对应位图中值为1,则证明存在,放入结果集中
        for (int i = maxValue; i >= 0 & index < result.length; --i) {
          if (bitmap[i] == 1) {
            result[index++] = i;
          }
        }
        return result;
      }
      
      public static void main(String[] args) {
        System.out.println("Sort begin...");
        long current = System.currentTimeMillis();
        int[] result = getTop(initArr());
        System.out.println(System.currentTimeMillis() - current);
        System.out.println("");
        System.out.println("result:");
        for (int i = 0; i < result.length; ++i) {
          System.out.print(result[i] + ",");
        }
      }
    

    相关文章

      网友评论

          本文标题:从100w个数中找到前10个最小的,并排序

          本文链接:https://www.haomeiwen.com/subject/ejqxsktx.html