堆排序获取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文 ...
随机推荐
- Windows线程的多任务处理
- SQL 行转列 列转行 PIVOT UNPIVOT
1.基础表 2.行转列,注意ISNULL函数的使用,在总成绩的统计中,ISNULL(-,0) 有必要使用 3.列转行,对列语文.数学.英语.政治,进行列转行,转为了2列,score scname 这两 ...
- Zephyr学习专题
1 前言 本来想学习Zyphyr的Power Management,但是看着看着就被带进去了. 你看功耗,里面的suspend涉及到时间补偿相关的吧,然后就涉及到了Kernel Clocks/Time ...
- ( 转)Ubuntu下创建、重命名、删除文件及文件夹,强制清空回收站方法
Ubuntu下创建.重命名.删除文件及文件夹,强制清空回收站方法 mkdir 目录名 ——创建一个目录 rmdir 空目录名 ——删除一个空目录 rm 文件名 文件名 ——删除一个文件或多个文件 rm ...
- flask-script&flask-migrate使用
一.简介 Flask-script扩展提供向Flask插入外部脚本的功能,包括运行一个开发用的服务器,一个定制的Python shell.设置数据库的脚本.cronjobs及其他运行在web应用之外的 ...
- NOI Day1线上同步赛梦游记
Preface 第一次体验NOI,虽然不是正式选手,但是打打同步赛还是挺涨姿势的,也算是体验了一把. Day1很爆炸,一方面是NOI题目的难度高于自身的水平,另一方面也出现了比较大的失误,T1一个数组 ...
- [Spark][Hive]Hive的命令行客户端启动:
[Spark][Hive]Hive的命令行客户端启动: [training@localhost Desktop]$ chkconfig | grep hive hive-metastore 0:off ...
- Spring Zuul 性能调优,如何提升平均响应时间200% ?
最近负责公司的 Gateway 项目,我们用 Spring Zuul 来做 HTTP 转发,但是发现请求多的时候,AWS 的健康检查就失败了,但是实际上程序还在跑,在日志上也没有任何东西错误打印出来出 ...
- Centos6下关于系统用户密码规则-运维笔记
随着linux使用的普遍,对于linux用户以及系统的安全要求越来越高,而用户密码复杂程度是系统安全性高低的首要体现.因此如何对linux下用户的密码进行规则限制,以保证用户必须使用复杂的密码,杜绝用 ...
- GCD实现同步方法
在iOS多线程中我们知道NSOperationQueue操作队列可以直接使用addDependency函数设置操作之间的依赖关系实现线程同步,还可以使用setMaxConcurrentOperatio ...