最(大)小堆的性质

(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. Top 10 questions about Java Collections--reference

    reference from:http://www.programcreek.com/2013/09/top-10-questions-for-java-collections/ The follow ...

  2. list add元素覆盖之前元素问题思考

    最近码墙时发现了一个很有意思的问题,定义一个引用对象,如果在循环外面定义对象,在循环里list.add(对象),最后的结果却是所有的对象值都是一样的,即每add一次,都会把之前所有的数据覆盖掉,蛮有趣 ...

  3. 自己动手,丰衣足食!一大波各式各样的ImageView来袭!

    工作略忙,一直想自己打造一个开源控件却苦于没有时间,可是这种事情如果不动手就会一直拖下去,于是最近抽时间做了个简单的自定义形状的ImageView控件. 时间紧迫,目前仅支持正六边形.圆形.菱形.椭圆 ...

  4. FineUI登入的例子中遇到的一些问题

    对于在使用FineUI这个例子的时候我们首先就是要在form标签内部添加一个 第一步. <ext:PageManager ID="PageManager1" runat=&q ...

  5. 构建本地yum源之rpmbuild问题汇总

    - check-rpaths的问题 今天在编译varnish的时候,遇到几个问题,其中一个就是出现如下错误: ...+ /usr/lib/rpm/check-rpaths /usr/lib/rpm/c ...

  6. C#汉字转拼音首字母

    输入汉字,提取其首字母: /// <summary> /// 汉字转拼音缩写 /// Code By /// 2004-11-30 /// </summary> /// < ...

  7. TCL 双引号和花括号的区别

    用了很一段时间的Modelsim,用TCL脚本仿真,开始注意起来它,看了些资料,有一个问题始终让我很困惑,那就是花括号 的用法,今天Google了一下,觉得有一点豁然了,记录一下.为了不让自己的翻译影 ...

  8. Magento 的程序架构与流程

    以下是分别详细解读分析程序的各层次源码: MAGENTO_ROOT: //入口文件 /index.php -----–| 1.判断php版本是否大于5.22.引入Magento主要的中心类/app/M ...

  9. .NET客户端下载SQL Server数据库中文件流保存的大电子文件方法(不会报内存溢出异常)

    .NET客户端下载SQL Server数据库中文件流保存的大电子文件方法(不会报内存溢出异常) 前段时间项目使用一次性读去SQL Server中保存的电子文件的文件流然后返回给客户端保存下载电子文件, ...

  10. JDBC对sql server的操作

    1.过程: 1>注册驱动器类:Class.forName()       2>连接数据库:             String url = "jdbc:sqlserver:// ...