插播面试题:海量数据求最大值Topk或者是最小值Topk

如果数据量堪称是海量的时候,我们还需要耗费大量的时间空间排序后在排序完成后取他们的前k个最大值或者是前k个最小值么?面对海量数据,并不要求所有的数据都排序成有序序列时,我们没有必要采用各式各样的排序算法对所有数都进行排序后再获得TopK值,这道题在面试题中可能会经常碰到,考察的就是排序中的堆排序。

输入:所有需要排序的数据,记作a1a2...ak,k值

输出:k个最大元素

对a1a2...ak建小顶堆(最小堆),根节点记为aroot

遍历剩余的元素,即ak+1ak+2ak+3....an:

如果元素值小于aroot,则跳过,此值和我们所需要的K个最大值一定是无关的。

如果元素值大于aroot,则将该元素和aroot替换,并调整堆,使得符合小顶堆。

遍历结束,小顶堆上所有的节点就是我们所需要求的最大值Topk。

相反,求最大值Topk则利用大顶堆。

那么为什么我们不能选择其他的排序方法呢?

在内部排序方法中,一趟排序后只有直接选择排序和起泡排序可以选出一个最大的或者是最小的元素,并加入到已有的有序子序列中,但是要比较n-1次,再选次大元素的时候有需要比较n-2词,这样排序的时间复杂度为O(n2)。如果是海量数据的话,则意味着n会很大,那么为了选择前k个最大的元素那么它的时间复杂度过大,不能采用这种方法。

而插入排序、快速排序、归并排序以及基数排序等排序方法虽然时间性能比较好,但是需要把所有元素都完全排序完成,直到最后才能确定各元素的位置。

而堆排序,在未结束全部排序前,就可以得出部分排序结果。在对前k个元素建立堆后,堆顶元素则是最大元素,调堆又能获得次大元素,这样就可以获得前k个最大元素。一般在数据量比较大时选出k个最大或者是最小的元素使用的一般是堆排序。

首先堆排序建堆比较的次数至多不超过4n,对于深度为k的堆,在调堆算法中关键字比较的次数至多为2(k-1)次,且辅助空间为O(1),所以在这种情况下我们会选择堆排序。

既然讲到了堆排序,下面就涉及以下堆排序的思想:

建堆过程:将待排序序列看作是一个完全二叉树,不断从n/2的下界开始筛选,不断筛选最终建成堆,可以看下面的建堆过程,图示为建小顶堆的过程。

调堆过程:将堆顶元素与堆的最后一个记录交换,之后将序列中的前n-1记录重新调整为堆,再将的堆顶记录和当前堆序列的最后一个记录交换,如此反复直到排序结束。

堆排序的优点:时间性能与树形选择排序属于同一量级,并且只需要一个记录大小供交换用的辅助空间,调堆时子女只和双亲比较。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值