堆排序获取TopN
package com.zjl.tool.sort; /**
* 求前面的最大K个 解决方案:小根堆 (数据量比较大(特别是大到内存不可以容纳)时,偏向于采用堆)
* @author 张恩备
* @date 2016-11-25 下午12:15:36
*/
public class TopNByHeap {
/**
* 待排序列(R1,R2,...,Rk,...Rn)看作是完全二叉树,通过比较、交换,父节点和孩子节点的值,
* 使得对于任意元素Rk(k<=n/2),满足Rk>=R(2k),Rk>=R(2k+1)
* @param arr 数组对象
* @param start 数组的开始下标
* @param end 数组的结束下标
*/
private static void HeapAdjust(int[] arr, int start, int end) {
//当下标为start的元素有孩子元素时
while(start <= end/2) {
//left和right分别为左右孩子元素的下标,max为左右孩子中值较小的孩子的元素下标
int left = 2 * start+1;
int right = 2 * start+2;
int min = 0; //如果既有左孩子,又有右孩子
if(left < end&&right <= end) {
//如果左孩子小于右孩子的值,max = right,否则为max = left
if(arr[left] <= arr[right])
min = left;
else
min = right;
}
//如果只有左孩子,没有右孩子,max值为left
if(left <= end&&right > end) {
min = left;
}
//如果没有孩子,则表明到了完全二叉树的叶子节点
if(left > end) {
break;
} //如果当前节点值小于两孩子中的值较大者,那么将当前节点值与max交换
if(arr[start] > arr[min]){
int tmp = arr[start];
arr[start] = arr[min];
arr[min] = tmp;
}
//当前节点向孩子节点迭代
start = min;
}
} /**
* 创建k个节点的小根堆
*
* @param a
* @param k
* @return
*/
static int[] createHeap(int a[], int k) {
int[] result = new int[k];
for (int i = 0; i < k; i++) {
result[i] = a[i];
}
//由最后一个非叶子节点,向根节点迭代,创建最大堆,数组中的最大值将被移动到根节点
for(int start = k-1/2;start >= 0;start--) {
HeapAdjust(result, start, k-1);
}
return result; } static void insert(int a[], int value, int k) {
//当输入元素的值value大于堆的根元素值时,则将堆的根元素的值赋值为输入元素的值value
a[0]=value;
//将改变后的堆重新k个节点的生成小根堆
for(int start = k-1/2;start >= 0;start--) {
HeapAdjust(a, start, k-1);
}
} static int[] getTopKByHeap(int input[], int k) {
int heap[] = createHeap(input, k);
for(int i=k;i<input.length;i++){
//当input[i]值大于堆的根元素值时,将input[i]插入到堆中
if(input[i]>heap[0]){
insert(heap, input[i], k);
}
} //将小根堆降序排列
while(k-1 > 0){
//交换arr[0]和arr[k-1]的值
int tmp = heap[0];
heap[0] = heap[k-1];
heap[k-1] = tmp; //待排序堆的范围变为依次减小,最后剩下一个元素时结束
//执行完这一步,根元素的值变为整个待序列中的最小值
HeapAdjust(heap, 0, k-2); k--;
}
return heap;
} public static void main(String[] args) {
int a[] = {40,55,49,73,12,27,98,81,64,36,78};
//获取top3
int result[] = getTopKByHeap(a, 3);
for (int temp : result) {
System.out.print(temp + " ");
}
}
}
堆排序获取TopN的更多相关文章
- 使用flink实现一个topN的程序
topN功能是一个非常常见的功能,比如查看最近几分钟的阅读最高数,购买最高数. flink实现topN的功能也非常方便,下面就开始构建一个flink topN的程序. 还是像上篇博客一样,从kafka ...
- 2. redis的数据类型
一. string类型 字符串类型是redis中最基本的数据类型,它能存储任何形式的内容,包含二进制数据,甚至是一张图片(二进制内容).一个字符串类型的值存储的最大容量是1GB 命令 (1)setnx ...
- oracle分页查询及原理分析(总结)
oracle分页查询及原理分析(总结) oracle分页查询是开发总为常用的语句之一,一般情况下公司框架会提供只需套用,对于增删改查而言,查是其中最为关键也是最为难的一块,其中就有使用率最高的分页查询 ...
- Python实现一些常用排序算法
一些常用的排序 #系统内置排序算法#list.sort()#heapq模块 def sys_heap_sort(list): import heapq heap = [] for i in range ...
- 通过python统计nginx日志定位php网站响应慢的问题
# 公司网站反映很慢,可能是一些页面的访问方法或者页面引起,通过程序统计nginx访问日志的页面和具体的action方法访问次数以及平均响应时间可以为程序开发的同事提供参考定位具体的代码 # 默认的n ...
- 020 RDD的理解
一:源码介绍RDD 1.RDD介绍 五大特性,保证了Spark的扩展性,容错性等特性. A list of partitions ====> 一个许多分区的集合,分区中包含数据 A functi ...
- hadoop学习day3 mapreduce笔记
1.对于要处理的文件集合会根据设定大小将文件分块,每个文件分成多块,不是把所有文件合并再根据大小分块,每个文件的最后一块都可能比设定的大小要小 块大小128m a.txt 120m 1个块 b.txt ...
- 智联招聘的python岗位数据结巴分词(二)
上次获取第一次分词之后的内容了 但是数据数据量太大了 ,这时候有个模块就派上用场了collections模块的Counter类 Counter类:为hashable对象计数,是字典的子类. 然后使用m ...
- python jieba 分词进阶
https://www.cnblogs.com/jiayongji/p/7119072.html 文本准备 到网上随便一搜"三体全集",就很容易下载到三体三部曲的全集文本(txt文 ...
随机推荐
- logstash同步mysql数据到mysql(问题一)
问题 通过logstash同步数据时 字段类型为tinyint时 通过过去 0变成了false 1变为了true 时间类型 变为 2018-10-16T14:58:02.871Z 分析 开始尝试通过 ...
- nested exception is org.apache.ibatis.reflection.ReflectionExceptio
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.Reflecti ...
- leetcode538. Convert BST to Greater Tree
https://www.cnblogs.com/grandyang/p/6591526.html 这个题本质上是中序遍历的反向.中序遍历是从小到大,而这个题目是从大到小,然后每个数加上比自己大的所有数 ...
- 【UOJ 17】飞扬的小鸟
UOJ 17 题意:在\(n\times m\)的网格中有一些柱子,它们可以通过的区间是\((L_i,R_i)\),位置在\(P_i\).在第i个位置点击一次会使高度增加\(X_i\),不点击会使高度 ...
- Apache Beam: 下一代的大数据处理标准
Apache Beam(原名Google DataFlow)是Google在2016年2月份贡献给Apache基金会的Apache孵化项目,被认为是继MapReduce,GFS和BigQuery等之后 ...
- Ionic 动态配置url路由的设置
随着Ionic App功能的不断增加,需要路由的url设置就越来越多,不喜欢在config函数中写一堆硬代码,一则不美,二则维护起来也麻烦,能不能把这些数据独立出来呢? 经过查找资料与各种实验,最终找 ...
- [Oralce][InMemory]如何确定一个表已经被Populate 到In Memory 中?
[Oralce][InMemory]如何确定一个表已经被Populate 到In Memory 中? 以如下方法来查看 POPULATE_STATUS 是不行的. SQL> select ins ...
- [Spark][Python]Spark 访问 mysql , 生成 dataframe 的例子:
[Spark][Python]Spark 访问 mysql , 生成 dataframe 的例子: mydf001=sqlContext.read.format("jdbc").o ...
- Spring Boot 2.0(七):Spring Boot 如何解决项目启动时初始化资源
在我们实际工作中,总会遇到这样需求,在项目启动的时候需要做一些初始化的操作,比如初始化线程池,提前加载好加密证书等.今天就给大家介绍一个 Spring Boot 神器,专门帮助大家解决项目启动初始化资 ...
- 我的devops实践经验分享一二
前言 随着系统越来越大,开发人员.站点.服务器越来越多,微服务化推进,......等等原因,实现自动化的devops越来越有必要. 当然,真实的原因是,在团队组建之初就预见到了这些问题,所以从一开始就 ...