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的更多相关文章

  1. 使用flink实现一个topN的程序

    topN功能是一个非常常见的功能,比如查看最近几分钟的阅读最高数,购买最高数. flink实现topN的功能也非常方便,下面就开始构建一个flink topN的程序. 还是像上篇博客一样,从kafka ...

  2. 2. redis的数据类型

    一. string类型 字符串类型是redis中最基本的数据类型,它能存储任何形式的内容,包含二进制数据,甚至是一张图片(二进制内容).一个字符串类型的值存储的最大容量是1GB 命令 (1)setnx ...

  3. oracle分页查询及原理分析(总结)

    oracle分页查询及原理分析(总结) oracle分页查询是开发总为常用的语句之一,一般情况下公司框架会提供只需套用,对于增删改查而言,查是其中最为关键也是最为难的一块,其中就有使用率最高的分页查询 ...

  4. Python实现一些常用排序算法

    一些常用的排序 #系统内置排序算法#list.sort()#heapq模块 def sys_heap_sort(list): import heapq heap = [] for i in range ...

  5. 通过python统计nginx日志定位php网站响应慢的问题

    # 公司网站反映很慢,可能是一些页面的访问方法或者页面引起,通过程序统计nginx访问日志的页面和具体的action方法访问次数以及平均响应时间可以为程序开发的同事提供参考定位具体的代码 # 默认的n ...

  6. 020 RDD的理解

    一:源码介绍RDD 1.RDD介绍 五大特性,保证了Spark的扩展性,容错性等特性. A list of partitions ====> 一个许多分区的集合,分区中包含数据 A functi ...

  7. hadoop学习day3 mapreduce笔记

    1.对于要处理的文件集合会根据设定大小将文件分块,每个文件分成多块,不是把所有文件合并再根据大小分块,每个文件的最后一块都可能比设定的大小要小 块大小128m a.txt 120m 1个块 b.txt ...

  8. 智联招聘的python岗位数据结巴分词(二)

    上次获取第一次分词之后的内容了 但是数据数据量太大了 ,这时候有个模块就派上用场了collections模块的Counter类 Counter类:为hashable对象计数,是字典的子类. 然后使用m ...

  9. python jieba 分词进阶

    https://www.cnblogs.com/jiayongji/p/7119072.html 文本准备 到网上随便一搜"三体全集",就很容易下载到三体三部曲的全集文本(txt文 ...

随机推荐

  1. mha高可用以及读写分离

    一.MHA简介 二.工作流程 三.MHA架构图 四.MHA工具介绍 五.基于GTID的主从复制 六.部署MHA 七.配置VIP漂移 八.配置binlog-server 九.MySQL中间件Atlas ...

  2. leetcode 104. Maximum Depth of Binary Tree 111. Minimum Depth of Binary Tree

    104: class Solution { public: int maxDepth(TreeNode* root) { if(root == NULL) ; int left = maxDepth( ...

  3. cisco ospf

    ospf配置:(Open Shortest Path First)PC0 and PC1 via Ospf to communicate. Network map as below.Environme ...

  4. C语言程序设计II—第八周教学

    第八周教学总结(15/4-21/4) 教学内容 本周的教学内容为: 8.4 电码加密 知识点:指针与字符串,重难点:字符指针与字符串的关联和区别: 8.5 任意个整数求和 知识点:动态内存分配的概念和 ...

  5. C# 程序默认使用管理员权限(转载)

    1.从A程序启动B程序,当B程序需要管理员权限的时候代码如下 A程序里面启动B程序的代码如下 ProcessStartInfo startInfo = new ProcessStartInfo(); ...

  6. Luogu3175 HAOI2015 按位或 min-max容斥、高维前缀和、期望

    传送门 套路题 看到\(n \leq 20\),又看到我们求的是最后出现的位置出现的时间的期望,也就是集合中最大值的期望,考虑min-max容斥. 由\(E(max(S)) = \sum\limits ...

  7. Task 异步编程测试案例及基础应用说明

    对于多线程,我们经常使用的是Thread.在我们了解Task之前,如果我们要使用多核的功能可能就会自己来开线程,然而这种线程模型在.net 4.0之后被一种称为基于“任务的编程模型”所冲击,因为tas ...

  8. Scala学习(七)---包和引入

    包和引入 摘要: 在本篇中,你将会了解到Scala中的包和引入语句是如何工作的.相比Java不论是包还是引入都更加符合常规,也更灵活一些.本篇的要点包括: 1. 包也可以像内部类那样嵌套 2. 包路径 ...

  9. 《Head First 设计模式》例子的C++实现(2 观察者模式)

    最近在学习设计模式,用的是 <Head First 设计模式>这本书.感觉这本书写的还是很不错的,深入浅出的介绍了各种常用的设计模式.唯一有点不方便的地方是这本书的例子全都是用的 Java ...

  10. python第二周

    第二周,PYTHON图形绘制 一,计算机技术的演进发展 1946-1981.从第一台计算机的诞生到IBM的PC机的出现,我们称之为”计算机系统结构时代“.————这个时代重点在解决计算能力问题 198 ...