从海量数据中寻找出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;
}
}
从海量数据中寻找出topK的最优算法代码的更多相关文章
- 海量数据中找出前k大数(topk问题)
海量数据中找出前k大数(topk问题) 前两天面试3面学长问我的这个问题(想说TEG的3个面试学长都是好和蔼,希望能完成最后一面,各方面原因造成我无比想去鹅场的心已经按捺不住了),这个问题还是建立最小 ...
- 原创:从海量数据中查找出前k个最小或最大值的算法(java)
现在有这么一道题目:要求从多个的数据中查找出前K个最小或最大值 分析:有多种方案可以实现.一.最容易想到的是先对数据快速排序,然后输出前k个数字. 二.先定义容量为k的数组,从源数据中取出前k个填 ...
- 面试突击 | Redis 如何从海量数据中查询出某一个 Key?附视频
1 考察知识点 本题考察的知识点有以下几个: Keys 和 Scan 的区别 Keys 查询的缺点 Scan 如何使用? Scan 查询的特点 2 解答思路 Keys 查询存在的问题 Scan 的使用 ...
- 【风马一族_C】c语言版,在2到n中寻找出所有的素数
#include <iostream> #include <stdio.h> #include <math.h> /* run this program using ...
- Redis实战(20)Redis 如何从海量数据中查询出某一个 Key?
序言 资料 https://www.cnblogs.com/vipstone/p/12373734.html
- 海量数据中的TOPK问题小结
1.利用堆找出最大的K个数 首先,先理解下用堆找出最大的K个数的常用解法,例如问题是“从M(M <= 10000)个数中找出最大的K个数” (1)利用最大堆 建立一个N=M大小的大顶堆,然后输出 ...
- 海量数据处理 - 10亿个数中找出最大的10000个数(top K问题)
前两天面试3面学长问我的这个问题(想说TEG的3个面试学长都是好和蔼,希望能完成最后一面,各方面原因造成我无比想去鹅场的心已经按捺不住了),这个问题还是建立最小堆比较好一些. 先拿10000个数建堆, ...
- 【跟着子迟品 underscore】如何优雅地写一个『在数组中寻找指定元素』的方法
Why underscore (觉得这部分眼熟的可以直接跳到下一段了...) 最近开始看 underscore.js 源码,并将 underscore.js 源码解读 放在了我的 2016 计划中. ...
- 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 ...
随机推荐
- C语言--简易词法分析器
#include <stdio.h>#include <stdlib.h>#include <string.h>int p,m,syn,n,sum; / ...
- angular复习笔记3-组件
组件Component 组件是构成angular应用的核心,angular的有序运行依赖于组件的协同工作,组件之于angular应用就像是汽车和汽车零部件的意思. 概述 近几年的前端发展迅速,各种工程 ...
- 反射之关于MethodInfo的使用
1.MethodInfo类是在System.Reflection命名空间底下,既然是在Reflection空间底下.故名思议关于反射相关的操作,其中比较重要的方法是Invoke()方法,它是加载相同程 ...
- Typora基础
Typora下载网址https://typora.io 一级标题 :# 空格 编写内容 二级标题 2*# 空格 内容 typora快捷键 ctrl+1 =一级标题 有序内容 1.+tab (Q旁边的t ...
- 面试官再问Redis分布式锁如何续期?这篇文章甩 他一脸
一.真实案例 二.Redis分布式锁的正确姿势 据肥朝了解,很多同学在用分布式锁时,都是直接百度搜索找一个Redis分布式锁工具类就直接用了.关键是该工具类中还充斥着很多System.out.prin ...
- 【转载】C#中Convert.ToSingle方法将字符串转换为Float类型
在C#编程过程中,可以使用Convert.ToSingle方法将字符串或者其他可转换为数字的对象变量转换为float类型,Convert.ToSingle方法有多个重载方法,最常使用的一个方法将字符串 ...
- 深入理解jvm--分代回收算法通俗理解
1.通俗的理解java对象的这一辈子 我是一个普通的java对象,我出生在Eden区,在Eden区我还看到和我长的很像的小兄弟,我们在Eden区中玩了挺长时间.有一天Eden区中的人实在是太多了,我就 ...
- Python的高级文件操作(shutil模块)
Python的高级文件操作(shutil模块) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 如果让我们用python的文件处理来进行文件拷贝,想必很多小伙伴的思路是:使用打开2个 ...
- 聊聊ThreadLocal源码(基于JDK1.8)
原文:https://cloud.tencent.com/developer/article/1333298 聊聊JDK源码中ThreadLocal的实现 主要方法: ThreadLocal的get方 ...
- MySQL:主键、外键、索引(一)
干货: 主键是关系表中记录的唯一标识.主键的选取非常重要:主键不要带有业务含义,而应该使用BIGINT自增或者GUID类型.主键也不应该允许NULL.可以使用多个列作为联合主键,但联合主键并不常用. ...