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

2020-08-26  本文已影响0人  chanyi

此类问题可以总结为从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] + ",");
    }
  }
上一篇下一篇

猜你喜欢

热点阅读