堆排序 海量数据求前N大的值
最(大)小堆的性质:
(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,再次交换
*/
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);
}
}
}
堆的删除
/** 堆的删除,每次都是删除堆顶的元素,删除后对堆进行调整* 具体做法是用堆尾部的元素代替堆顶元素,然后调整堆*/
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/
堆排序 海量数据求前N大的值的更多相关文章
- 算法导论学习之线性时间求第k小元素+堆思想求前k大元素
对于曾经,假设要我求第k小元素.或者是求前k大元素,我可能会将元素先排序,然后就直接求出来了,可是如今有了更好的思路. 一.线性时间内求第k小元素 这个算法又是一个基于分治思想的算法. 其详细的分治思 ...
- BZOJ2006:超级钢琴(ST表+堆求前K大区间和)
Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度 ...
- 牛客第六场 J.Heritage of skywalkert(On求前k大)
题目传送门:https://www.nowcoder.com/acm/contest/144/J 题意:给一个function,构造n个数,求出其中任意两个的lcm的最大值. 分析:要求最大的lcm, ...
- HDU 6041 I Curse Myself(点双联通加集合合并求前K大) 2017多校第一场
题意: 给出一个仙人掌图,然后求他的前K小生成树. 思路: 先给出官方题解 由于图是一个仙人掌,所以显然对于图上的每一个环都需要从环上取出一条边删掉.所以问题就变为有 M 个集合,每个集合里面都有一堆 ...
- TZOJ 1242 求出前m大的数(预处理)
描述 给定一个包含N(N<=3000)个正整数的序列,每个数不超过5000,对它们两两相加得到的N*(N-1)/2个和,求出其中前M大的数(M<=10000)并按从大到小的顺序排列. 输入 ...
- 两个序列求前k大和
---恢复内容开始--- 没有题目,没有题意,这是学长提过的一个技巧,给你两个排好序的序列,每次可以各从中取一个,求前k大的和, 一个优先队列,先将a序列中最大的那个和b序列所有元素相加存进队列中,每 ...
- 查找第K大的值
这种题一般是给定N个数,然后N个数之间通过某种计算得到了新的数列,求这新的数列的第K大的值 POJ3579 题意: 用$N$个数的序列$x[i]$,生成一个新序列$b$. 新的序列定义为:对于任意的$ ...
- 面试题:求第K大元素(topK)?
一.引言二.普通算法算法A:算法B:三.较好算法算法C:算法D:四.总结 一.引言 这就是类似求Top(K)问题,什么意思呢?怎么在无序数组中找到第几(K)大元素?我们这里不考虑海量数据,能装入内 ...
- 算法---数组总结篇2——找丢失的数,找最大最小,前k大,第k小的数
一.如何找出数组中丢失的数 题目描述:给定一个由n-1个整数组成的未排序的数组序列,其原始都是1到n中的不同的整数,请写出一个寻找数组序列中缺失整数的线性时间算法 方法1:累加求和 时间复杂度是O(N ...
随机推荐
- WPF柱状图(支持数据库动态更新)之组件的数据动态化
WPF柱状图(支持数据库动态更新) 在这片文章中我们介绍了如何将柱状图包装成一个组件,将这个组件的属性对外开放和组件的外部属性根内部属性绑定以及非轮询动态更新数据的方式. 非轮询更新数据感觉介绍的不够 ...
- JSTL-core核心代码标签库中的forEach,remove, forTokens,choose,when,otherwise,redirect 标签
<%@ page language="java" import="java.util.*, cn.hncu.domain.*" pageEncoding= ...
- 8.LNMP环境的配置
LNMP环境的配置 参照文档:https://oneinstack.com/install/ 安装文件位置:/data/soft: ```yum -y install wget screen pyth ...
- centos6 install mplayer(multimedia)
step_1 http://wiki.centos.org/AdditionalResources/Repositories/RPMForge step_2 http://wiki.centos.or ...
- how to forget about delta cycles for RTL design
A delta cycle is a VHDL construct used to makeVHDL, a concurrent language, executable on asequential ...
- GridView中使用如下button OnClientClick代码会出现解析错误
在GridView中使用如下代码会出现解析错误: <asp:LinkButton ID="DeleteButton" runat="server" Cau ...
- redux学习笔记
中文api:http://cn.redux.js.org/docs/react-redux/troubleshooting.html 3.6 Reducer Store 收到 Action 以后,必须 ...
- 设置repeater每行多少个的方法
前台代码: <asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server">< ...
- jdbc-connect-oracle12c-pdb/cdb(jdbc连接oracle12c的pdb和cdb)
1 本文简介: 通过特意引发问题,聚焦问题,解决问题,并循序渐进 最后总结jdbc连接oracle12c中cdb和pdb的条件. 软件环境:Redhat7.1+orcacle12c 2 ...
- UItextField常用方法
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view ...