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;
 }
}

从海量数据中寻找出topK的最优算法代码的更多相关文章

  1. 海量数据中找出前k大数(topk问题)

    海量数据中找出前k大数(topk问题) 前两天面试3面学长问我的这个问题(想说TEG的3个面试学长都是好和蔼,希望能完成最后一面,各方面原因造成我无比想去鹅场的心已经按捺不住了),这个问题还是建立最小 ...

  2. 原创:从海量数据中查找出前k个最小或最大值的算法(java)

    现在有这么一道题目:要求从多个的数据中查找出前K个最小或最大值 分析:有多种方案可以实现.一.最容易想到的是先对数据快速排序,然后输出前k个数字.   二.先定义容量为k的数组,从源数据中取出前k个填 ...

  3. 面试突击 | Redis 如何从海量数据中查询出某一个 Key?附视频

    1 考察知识点 本题考察的知识点有以下几个: Keys 和 Scan 的区别 Keys 查询的缺点 Scan 如何使用? Scan 查询的特点 2 解答思路 Keys 查询存在的问题 Scan 的使用 ...

  4. 【风马一族_C】c语言版,在2到n中寻找出所有的素数

    #include <iostream> #include <stdio.h> #include <math.h> /* run this program using ...

  5. Redis实战(20)Redis 如何从海量数据中查询出某一个 Key?

    序言 资料 https://www.cnblogs.com/vipstone/p/12373734.html

  6. 海量数据中的TOPK问题小结

    1.利用堆找出最大的K个数 首先,先理解下用堆找出最大的K个数的常用解法,例如问题是“从M(M <= 10000)个数中找出最大的K个数” (1)利用最大堆 建立一个N=M大小的大顶堆,然后输出 ...

  7. 海量数据处理 - 10亿个数中找出最大的10000个数(top K问题)

    前两天面试3面学长问我的这个问题(想说TEG的3个面试学长都是好和蔼,希望能完成最后一面,各方面原因造成我无比想去鹅场的心已经按捺不住了),这个问题还是建立最小堆比较好一些. 先拿10000个数建堆, ...

  8. 【跟着子迟品 underscore】如何优雅地写一个『在数组中寻找指定元素』的方法

    Why underscore (觉得这部分眼熟的可以直接跳到下一段了...) 最近开始看 underscore.js 源码,并将 underscore.js 源码解读 放在了我的 2016 计划中. ...

  9. hdu 1595 find the longest of the shortest【最短路枚举删边求删除每条边后的最短路,并从这些最短路中找出最长的那条】

    find the longest of the shortest Time Limit: 1000/5000 MS (Java/Others)    Memory Limit: 32768/32768 ...

随机推荐

  1. C# vb .net实现锐化效果滤镜

    在.net中,如何简单快捷地实现Photoshop滤镜组中的锐化效果呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第一步 ...

  2. Node.js到底是什么

    接触前端也有一段时间了,逐渐开始接触Node.js,刚刚接触Node.js的时候一直都以为Node.js就是JavaScript,当对Node.js有一定的了解之后,其实并不然两者之间有关系,其中的关 ...

  3. python通过装饰器检查函数参数的数据类型的代码

    把内容过程中比较常用的一些内容记录起来,下面内容段是关于python通过装饰器检查函数参数的数据类型的内容. def check_accepts(f): assert len(types) == f. ...

  4. 魅族手机使用应用沙盒一键修改imsi数据

    较早前文章介绍了怎么在安卓手机上安装激活XPosed框架,XPosed框架的牛逼之处功能各位都介绍过,可以不修改apk的前提下,修改系统内核的参数,打比方在某些应用领域,各位需要修改手机的某个系统参数 ...

  5. wokerman随笔

    linux环境检查是否满足workerman要求: curl -Ss http://www.workerman.net/check.php | php workerman依赖扩展:pcntl扩展.po ...

  6. 【DATAGUARD】物理dg配置客户端无缝切换 (八.2)--Fast-Start Failover 的配置

    [DATAGUARD]物理dg配置客户端无缝切换 (八.2)--Fast-Start Failover 的配置 一.1  BLOG文档结构图       一.2  前言部分   一.2.1  导读 各 ...

  7. Linux系统 jboss/Tomcat服务器pdf文件乱码问题

    1.新搭建的环境,但是没有字符集,在windows上的电脑上复制了一份宋体, 字体C:\WINDOWS\FONTS\simsun.ttc(也就是宋体,大小为10M),把他重命名为 simsun.ttf ...

  8. Python的包管理工具

    Python的包管理工具 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.为什么使用包管理 Python的模块或者源文件直接可以复制到目标项目目录中,就可以导入使用了. 但是为了 ...

  9. Jenkins服务器的安装

    Jenkins服务器的安装 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.安装jdk 详情请参考:https://www.cnblogs.com/yinzhengjie/p/1 ...

  10. MSSQL-反弹注入

    工具:香港云免费云服务器:http://www.webweb.com 注册使用匿名邮箱:https://bccto.me/ 香港云服务器搭建MSSQL数据库,并建表admin,字段数要大于等于我们想要 ...