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. SpringCloud微服务基础学习

    看了蚂蚁课堂的微服务学习,确实学习了不少关于微服务的知识,现在总结学习如下 : SpringCloud微服务基础单点系统架构传统项目架构传统项目分为三层架构,将业务逻辑层.数据库访问层.控制层放入在一 ...

  2. Java——简单实现学生管理系统

    import java.io.*;import java.util.ArrayList;import java.util.Scanner;class MyObjectOutputStream exte ...

  3. Golang中的RegExp正则表达式用法指南

    ------------------------------------------------------------ Golang中的正则表达式 ------------------------- ...

  4. 微信JS-SDK实现分享功能

    1 申请一个微信公众号,并确认在开发–接口权限中拥有分享功能的权限. 2 公众号设置–功能设置:在JS接口安全域名中添加安全域名,这个安全域名不是url,只需添加一级域名即可. 3 开发,基本配置中, ...

  5. 自学Python编程的第九天(希望有大牛帮我看看我第一个代码是否有弊端,感谢您们)----------来自苦逼的转行人

    2019-09-19-22:11:33 今天是自学Python的第九天 学的内容是有关文件操作的,如:r.w.a.rb.wb.ab.r+.w+.a+等 有大牛帮我看一下我的代码第一个有没有什么弊端吗? ...

  6. MySQL语法顺序及执行顺序

    一.书写顺序 select[distinct] from join on where group by having union order by limit 二.执行顺序 from on join ...

  7. 关于justify-content属性的再学习(区分三个属性)

    justify-content属性: 用来表示可伸缩项目在主轴方向上的对齐方式: 取值范围为flex-start,flex-end,center,space-between,space-around: ...

  8. 正则表达式修饰符 i、g、m、s、U、x、a、D、e 等。

    正则表达式中常用的模式修正符有i.g.m.s.U.x.a.D.e 等. 它们之间可以组合搭配使用. i 不区分(ignore)大小写: 例如: /abc/i 可以匹配 abc.aBC.Abc g 全局 ...

  9. zookeeper 事务日志查看

    在version下的日志是二进制文件,查看需要转换 创建/data/middleware/zookeeper-3.4.14/translog.sh 脚本 格式化命令: java -classpath ...

  10. jenkins使用邮件功能

    jenkins发送邮件 在日常构建后,需要及时将构建结果发送给相应的人员.这时就可以使用jenkins自带的邮件配置系统. 1 开通邮箱的SMTP服务,需要发送短信验证开启 2 进入"系统管 ...