zoukankan      html  css  js  c++  java
  • 从海量数据中寻找出topK的最优算法代码

    package findMinNumIncludedTopN;
    /**
     * 小顶堆
     * @author TongXueQiang
     * @date 2016/03/09
     * @since JDK 1.8
     */
    public class MinHeap {
     int[] heap;
     int heapsize;

     public MinHeap(int[] array) {
      this.heap = array;
      this.heapsize = heap.length;
     }
     
     /**
      * 构建小顶堆
      */
     public void BuildMinHeap() {
      for (int i = heapsize / 2 - 1; i >= 0; i--) {
       Minify(i);// 依次向上将当前子树最大堆化
      }
     }
     
     /**
      * 堆排序
      */
     public void HeapSort() {
      for (int i = 0; i < heap.length; i++) {
       // 执行n次,将每个当前最大的值放到堆末尾
       swap(heap,0,heapsize-1);   
       heapsize--;
       Minify(0);
      }
     }
     
     /**
      * 对非叶节点调整
      * @param i
      */
     public void Minify(int i) {
      int l = 2*i + 1;
      int r = 2*i + 2;
      int min;

      if (l < heapsize && heap[l] < heap[i])
       min = l;
      else
       min = i;
      if (r < heapsize && heap[r] < heap[min])
       min = r;
      if (min == i || min >= heapsize)// 如果largest等于i说明i是最大元素
                // largest超出heap范围说明不存在比i节点大的子女
       return;
      swap(heap,i,min);
      Minify(min); 
     }

     private void swap(int[] heap, int i, int min) {
      int tmp = heap[i];// 交换i与largest对应的元素位置,在largest位置递归调用maxify
      heap[i] = heap[min];
      heap[min] = tmp;  
     }

     public void IncreaseValue(int i, int val) {
      heap[i] = val;
      if (i >= heapsize || i <= 0 || heap[i] >= val)
       return;
      int p = Parent(i);
      if (heap[p] >= val)
       return;
      heap[i] = heap[p];
      IncreaseValue(p, val);
     }

     private int Parent(int i) {
      return (i - 1) / 2;
     }
    }

    package findMinNumIncludedTopN;

    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileReader;
    import java.io.IOException;

    /**
     * 从海量数据中查找出前k个最大值,精确时间复杂度为:k + (n - k) * lgk,空间复杂度为 O(k),目前为所有算法中最优算法
     *
     * @author TongXueQiang
     * @date 2016/03/08
     * @since JDK 1.8
     */
    public class FindMinNumIncluedTopN {
     /**
      * 从海量数据中查找出前k个最大值
      *
      * @param k
      * @return
      * @throws IOException
      */
     public int[] findMinNumIncluedTopN(int k) throws IOException {
      Long start = System.nanoTime();
      
      int[] array = new int[k];
      int index = 0;
      // 从文件导入海量数据
      BufferedReader reader = new BufferedReader(new FileReader(new File("F:/number.txt")));
      String text = null;
      // 先读出前n条数据,构建堆
      do {
       text = reader.readLine();
       if (text != null) {
        array[index++] = Integer.parseInt(text);
       }   
      } while (text != null && index <= k - 1);
      
      MinHeap heap = new MinHeap(array);//初始化堆
      for (int i : heap.heap) {
       System.out.print(i + " ");
      }
      
      heap.BuildMinHeap();//构建小顶堆
      System.out.println();
      System.out.println("构建小顶堆之后:");
      for (int i : heap.heap) {
       System.out.print(i + " ");
      }
      System.out.println();
      // 遍历文件中剩余的n(文件数据容量,假设为无限大)-k条数据,如果读到的数据比heap[0]大,就替换之,同时更新堆
      while (text != null) {
       text = reader.readLine();
       if (text != null && !"".equals(text.trim())) {
        if (Integer.parseInt(text) > heap.heap[0]) {
         heap.heap[0] = Integer.parseInt(text);
         heap.Minify(0);//调整小顶堆
        }
       }
      }
      //最后对堆进行排序(默认降序)
      heap.HeapSort();
      
      Long end = System.nanoTime();
      double time = (end - start) / Math.pow(10,9);
      System.out.println("用时:"+ time + "秒");
      for (int i : heap.heap) {
       System.out.println(i);
      }
      return heap.heap;
     }
    }

  • 相关阅读:
    【bzoj1010】[HNOI2008]玩具装箱toy
    bzoj 3173
    bzoj 1179
    bzoj 2427
    bzoj 1051
    bzoj 1877
    bzoj 1066
    bzoj 2127
    bzoj 1412
    bzoj 3438
  • 原文地址:https://www.cnblogs.com/txq157/p/6165489.html
Copyright © 2011-2022 走看看