堆排序获取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文 ...
随机推荐
- (二 -2) 天猫精灵接入Home Assistant-自动发现Mqtt设备
参考中文教程: https://www.hachina.io/docs/7230.html 英文官网 两个温度传感器:https://www.home-assistant.io/docs/mqtt/ ...
- JS进阶之---作用域,作用域链,闭包
一.作用域: 在JavaScript中,我们可以将作用域定义为一套规则,这套规则用来管理引擎如何在当前作用域以及嵌套的子作用域中根据标识符名称进行变量查找.这里的标识符,指的是变量名或者函数名. Ja ...
- day14 Python函数
函数def,严格来讲有个return返回值 过程就是没有return返回值的函数 #过程 def test01(): msg = 'liuhaoran' print(msg) #函数 def test ...
- JMS和AMQP的区别
JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信 ...
- 4.5《想成为黑客,不知道这些命令行可不行》(Learn Enough Command Line to Be Dangerous)—第四章小结
本章相关重要命令总结在Table 6. 命令 描述 示例 mkdir <name> 创建某目录 $ mkdir foo pwd 显示当前所在目录 $ pwd cd <dir> ...
- Luogu4547 THUWC2017 随机二分图 概率、状压DP
传送门 考虑如果只有$0$组边要怎么做.因为$N \leq 15$,考虑状压$DP$.设$f_i$表示当前的匹配情况为$i$时的概率($i$中$2^0$到$2^{N-1}$表示左半边的匹配情况,$2^ ...
- Vue-认识状态管理vuex
vuex是一个专门为vue.js设计的状态管理模式,并且也可以使用devtools进行调试,可以多个组件共享状态.简单来说,就是共享的状态用state来存放,用mutations来操作state,但是 ...
- prop和attr的比较
prop来获取或设置固有属性 removeProp() 删除固有属性 attr来获取或设置自定义属性 removeAttr() 删除自定义属性 案例:全选与全不选 <body> ...
- select 下拉选中
<body> <select name="" id=""> <option value="">张三< ...
- 控制反转IOC与依赖注入DI - 理论篇
学无止境,精益求精 十年河东十年河西,莫欺少年穷 昨天是五一小长假归来上班的第一天,身体疲劳,毫无工作热情.于是就看看新闻,喝喝茶,荒废了一天 也就在昨天,康美同事张晶童鞋让我学习下IOC的理论及实现 ...