最(大)小堆的性质

(1)是一颗完全二叉树,遵循完全二叉树的所有性质。

(2)父节点的键值(大于)小于等于子节点的键值

堆的存储

一般都用数组来表示堆,i结点的父结点下标就为(i – 1) / 2。它的左右子结点下标分别为2 * i + 1和2 * i + 2。如第0个结点左右子结点下标分别为1和2。

海量数据前n大,并且n比较小,堆可以放入内存

【基本原理及要点】

          最大堆求前n小,最小堆求前n大。方法,比如求前n小,我们比较当前元素与最大堆里的最大元素,如果它小于最大元素,则应该替换那个最大元 素。这样最后得到的n个元素就是最小的n个。适合大数据量,求前n小,n的大小比较小的情况,这样可以扫描一遍即可得到所有的前n元素,效率很高。

【扩展】

          双堆,一个最大堆与一个最小堆结合,可以用来维护中位数。

建立堆

        /**

* 将建立堆的过程看作是每次向堆中插入一个数据

* 每次插入数据都是在插入堆的尾部,然后进行堆调整

* 说明:每次调整的时候,只需要向上调整即可,由于每次调整之后的子节点的值总是大于父节点

*     当前插入放入节点向上一层一层调整时,始终保持子堆依然是最小堆结构

*     如      10

*             /     \

*           14     17

*          /   \     /   \

*       18  15 20   37

*      插入节点13时,13为18的子节点,需交换,此时13为父节点,同时由于13小于14,再次交换
         *      注意这里不要调整13的子树的结构,因为13的子树都是向上调整子最小堆得来,因此13的子树本身满足最小堆结构

*/

 java代码实现
void minHeapBuild(int[] num,int index){
//num[0,1..index-1]为已经实现的最小堆,index为插入num[index]值,建立新的堆
int length=num.length;
if(length<=0)
return;
int p=parent(index);
while(p>=0&&index!=0){
if(num[index]>=num[p])
break;
else{
//交换节点
int tmp=num[index];
num[index]=num[p];
num[p]=tmp; //重定位当前节点
index=p;
p=parent(index);
}
}
}

堆的删除

         /** 堆的删除,每次都是删除堆顶的元素,删除后对堆进行调整* 具体做法是用堆尾部的元素代替堆顶元素,然后调整堆*/

java代码实现
void minHeapDelete(int[] num, int len){
int length=num.length;
if(len>=length||len==0)
return;
int p=0;
int child=leftChild(p);
num[p]=num[len-1];//堆尾元素置于堆顶
while(child<len){
//找到左右子节点的较小值
if(child+1<len && num[child]>num[child+1])
child+=1;
if(num[p]<=num[child])
break;
else{
//交换节点
int tmp=num[child];
num[child]=num[p];
num[p]=tmp; //重定位当前父节点
p=child;
child=leftChild(p);
}
} }
int parent(int i){return (i-1)/2;}
int leftChild(int i){return 2*i+1;}

部分参考:http://blog.163.com/xychenbaihu@yeah/blog/static/132229655201351984231220/

                 http://blog.csdn.net/morewindows/article/details/6709644/


堆排序 海量数据求前N大的值的更多相关文章

  1. 算法导论学习之线性时间求第k小元素+堆思想求前k大元素

    对于曾经,假设要我求第k小元素.或者是求前k大元素,我可能会将元素先排序,然后就直接求出来了,可是如今有了更好的思路. 一.线性时间内求第k小元素 这个算法又是一个基于分治思想的算法. 其详细的分治思 ...

  2. BZOJ2006:超级钢琴(ST表+堆求前K大区间和)

    Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度 ...

  3. 牛客第六场 J.Heritage of skywalkert(On求前k大)

    题目传送门:https://www.nowcoder.com/acm/contest/144/J 题意:给一个function,构造n个数,求出其中任意两个的lcm的最大值. 分析:要求最大的lcm, ...

  4. HDU 6041 I Curse Myself(点双联通加集合合并求前K大) 2017多校第一场

    题意: 给出一个仙人掌图,然后求他的前K小生成树. 思路: 先给出官方题解 由于图是一个仙人掌,所以显然对于图上的每一个环都需要从环上取出一条边删掉.所以问题就变为有 M 个集合,每个集合里面都有一堆 ...

  5. TZOJ 1242 求出前m大的数(预处理)

    描述 给定一个包含N(N<=3000)个正整数的序列,每个数不超过5000,对它们两两相加得到的N*(N-1)/2个和,求出其中前M大的数(M<=10000)并按从大到小的顺序排列. 输入 ...

  6. 两个序列求前k大和

    ---恢复内容开始--- 没有题目,没有题意,这是学长提过的一个技巧,给你两个排好序的序列,每次可以各从中取一个,求前k大的和, 一个优先队列,先将a序列中最大的那个和b序列所有元素相加存进队列中,每 ...

  7. 查找第K大的值

    这种题一般是给定N个数,然后N个数之间通过某种计算得到了新的数列,求这新的数列的第K大的值 POJ3579 题意: 用$N$个数的序列$x[i]$,生成一个新序列$b$. 新的序列定义为:对于任意的$ ...

  8. 面试题:求第K大元素(topK)?

    一.引言二.普通算法算法A:算法B:三.较好算法算法C:算法D:四.总结 一.引言 ​ 这就是类似求Top(K)问题,什么意思呢?怎么在无序数组中找到第几(K)大元素?我们这里不考虑海量数据,能装入内 ...

  9. 算法---数组总结篇2——找丢失的数,找最大最小,前k大,第k小的数

    一.如何找出数组中丢失的数 题目描述:给定一个由n-1个整数组成的未排序的数组序列,其原始都是1到n中的不同的整数,请写出一个寻找数组序列中缺失整数的线性时间算法 方法1:累加求和 时间复杂度是O(N ...

随机推荐

  1. careercup-递归和动态规划 9.6

    9.6 实现一种算法,打印n对括号的全部有效组合(即左右括号正确配对). 类似leetcode:Generate Parentheses 解法: 从头开始构造字符串,从而避免出现重复字符串.在这个解法 ...

  2. 【转】VS2010中使用AnkhSvn

    今天想到要在自己的开发环境IDE(Visual Studio 2010)中安装一个代码管理器的插件,本人在使用VS2005的时候一直都是使用AnkhSvn-2.1.7444.278这版本,使用过程中也 ...

  3. L2TP

    点击查看详情>>   我的贡献 |退出 L2TP 编辑词条 L2TP是一种工业标准的Internet隧道协议,功能大致和PPTP协议类似,比如同样可以对网络数据流进行加密.不过也有不同之处 ...

  4. 常见资源记录定义(Resource Record)

    所有的RRs(Resource Records)都具有相同的顶级字段格式定义:owner  TTL CLASS TYPE RDATA owner 指示拥有资源记录的DNS域名 TTL 对大多数资源记录 ...

  5. IIS限制ASP.Net 文件上传大小解决方案,修改IIS7/7.5配置

    当在web.config中设置了 httpruntime 后还是无法成功上传大文件,则要修改IIS的系统config IIS 7 默认文件上传大小是30M 要突破这个限制: 修改IIS的applica ...

  6. php中的全局变量引用

    全局变量在函数外部定义,作用域为从变量定义处开始,到本程序文件的末尾.但和其他语言不同,php的全局变量不是自动设为可用的,在php中函数可以视为单独的程序片段,局部变量会覆盖全局变量的能见度,因此, ...

  7. 使用DOM4J解析XMl文件与读取XML文件

    XML文件 <?xml version="1.0" encoding="UTF-8"?> <bookstore> <book id ...

  8. c#进程间通讯方案之IPC通道

    转载:http://www.cnphp.info/csharp-ipc-channel-remoting.html 最近一直纠结与使用多进程还是多线程来构建程序.多线程的方法似乎不错,但是一个进程可承 ...

  9. Java编程风格与命名规范整理

    基本命名规范 包命名 包名按照域名的范围从大到小逐步列出,恰好和Internet上的域名命名规则相反. 由一组以“.”连接的标识符构成,通常第一个标识符为符合网络域名的两个或者三个英文小写字母. Pe ...

  10. O-C相关-07-@property关键字简介与使用

    基本概念:在O-C中,创建完类之后还需要给一个类添加属性和方法,之前说过的set和get方法比较繁琐,因此引入了@property 这个编译器指令.@property 是一个编译器指令.所谓的编译器指 ...