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. Java知识回顾 (15) 文档注释

    说明注释允许你在程序中嵌入关于程序的信息. 你可以使用 javadoc 工具软件来生成信息,并输出到HTML文件中,使你更加方便的记录你的程序信息. javadoc 标签 标签 描述 示例 @auth ...

  2. 【Java基础】- Java学习路线图

    Java的学习路线图,整理以备自己学习和温习. 1.Java基础 具体内容: 1. 编程基础(开发环境配置.基础语法.基本数据类型.流程控制.常用工具类) 2. 面向对象(继承.封装.多态.抽象类.接 ...

  3. CAS 的问题

    cas这么好用,那么有没有什么问题呢?还真有 ABA问题 CAS需要在操作值的时候检查下值有没有发生变化,如果没有发生变化则更新,但是如果一个值原来是A,变成了B,又变成了A,那么使用CAS进行检查时 ...

  4. 三、Linux_环境变量

    环境变量配置: # 每次进入命令都要重新source /etc/profile 才能生效? # 解决办法:将环境变量放置到~/.bashrc文件中 $ vim ~/.bashrc # 在里面添加相关的 ...

  5. golang并发基础

    1. go协程(go routine) go原生支持并发:goroutine和channel. go协程是与其他函数或方法一起并发运行的函数和方法.go协程可以看作是轻量级线程. 调用函数或者方法时, ...

  6. job和cronjob的使用

    job和cronjob的使用 我们在工作中会遇到需要批量处理数据和分析的需求,也会有按时间来进行调度的工作,在k8s集群中,有job和cronjob两中资源对象来映带我们的这种需要. job负责处理任 ...

  7. 数据库开发-Django ORM的数据库迁移

    数据库开发-Django ORM的数据库迁移 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一. Django 项目准备 1>.安装django包 pip install d ...

  8. 发布WS接口与实现WS接口[小列子]

    webservice简介:Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的.专门的第三方软件或硬件, 就可相互交换数据或集成.依据Web Service规范实施的应用之间, ...

  9. MYSQL中常见的时间处理

    use test; select getdate() select sysdate(); select now(); select current_timestamp select current_t ...

  10. springboot整合mybatis及封装curd操作-配置文件

    1 配置文件  application.properties  #server server.port=8090 server.address=127.0.0.1 server.session.tim ...