海量数据处理之归并、堆排、前K方法的应用

本文深入探讨了在处理海量数据时,如何高效地找出前K大元素的问题。主要介绍了两种解决方案:堆排序和K选择。详细解释了这两种方法的工作原理、复杂度,并通过对比分析,给出了不同场景下更优的选择策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于海量数据“寻找前K大”,目前总结起来我想一般也就两种方案:堆排序、K选择。

这里需要说明两点:

(1)如果数据量比较大,一般我们认为K>2,如果K<2,遍历一遍即可求,无需过多讨论

(2)如果数据量不是太大,完全可以做K次冒泡来求得

这里我们考虑的是数据量比较大,K>2的情况

当然,还有其他方法,欢迎留言补充。

  • 堆排序

       网上对于解决海量前K大问题比较常用的方法就是堆排。我们知道,使用堆排序是要求堆可以放入内存啊,这么大的数据,怎么放?这里有一个技巧,内存中并不是放入所有数据的堆,而是放入K大小的堆,我们知道堆调整的复杂度为lgK,使用K大小的堆,文件遍历一遍我们就可以求出前K大,所以复杂度是NlgK,N是词的个数,只不过这个“遍历”是文件操作,系数要比在内存中“遍历”的系数要大一些。

方案:将统计好的词频取K个放入内存,调整为最小堆,注意这里是最小堆,求前K大,比较当前的元素与最小堆当中的最小元素,如果它大于最小元素则替换那个最小元素,这样最后得到的K个元素就是最大的K个。反之,求前K小,用的自然就是最大堆啦。

  • K选择

       K选择是用于求第K大的元素,其实“求前K大”等价于“求第K大”,对数据运行一次K选择算法,那么前K大的元素不就都有了么。但是问题是K选择也需要放入内存啊,这么大的数据又放不下了,肿么办?是的,又是归并的思想。不过这里为大家提供两种可行的方案,方案1使用归并的思想,方案2是直接用K选择的外排序,几乎不需要内存,此为大雄原创,O(∩_∩)O~。

此外,如果大家有更好的方法,欢迎留言补充,谢谢!

方案1:我当时的想法是,将统计好的词频分段,先在内存中求出每段的前K大,然后各段的前K大有了,再将这几段的前K大放入内存求得最终的前K大

方案2:直接使用文件运行前K大算法。思路是开两个文件,选取轴数后一个文件放入大数,一个文件放小数,同时记录各文件放入的数目,从而直接用文件得到最终的前K大。这样做只是时间上耗费可能要多一些

  • 堆排 & K选择的对比分析

这里对两种方法做一个简单的分析:复杂度。

前K堆方法的复杂度为NlgK,N为词总数。

K选择方法复杂度:N + 1/2 + 1/4 + … = 2N. (类似快排:快排是N + N + N + … 共lgN个),这样看起来貌似前K快一点,呵呵,实际上还要考虑系数的问题,例如操作文件比操作内存的系数必然要大,一般来讲:只能说K很小的时候,堆比较快;K很大的时候,前K比较快吧。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值