首页 > 代码库 > 简单的topK问题

简单的topK问题

/************************************************************************//* 求一组数据中的top(K)问题,这是一个经典的top(K)问题。分析:方法一:如果数据量不大,那么最常用的方法就是排序从大大小,然后找出前k个数据。比较高效率的排序算法,如快排,堆排序等,总体时间复杂度为 O(N*log2(N))+O(K)=O(N*log2(N))或是直接用部分排序算法,如选择排序,直接找出前K个元素,时间复杂度为O(N*K),至于O(N*log2(N)) 还是O(N*K)效率高,看K的取值,若K<log2(N)那么部分排序效率高。方法二:如果数据量非常大,不能够加载到内存中,这就成了一个海量数据问题。求其中的top(K)就是我们所求的前K个大的数据。这样考虑,我们用一个长度为K大小的数组存储前k个数据,然后经过一次扫描数据,每次扫描一个数据,和数据中最小的数据比较,如果小于这个数据,继续下一个数据扫描,如果大于这个数据,那么就替换掉数组中最小的那个数据。这样所消耗的时间效率为O(N*K)进一步,我们可以用容量为K大小的最小堆来存储前K个数据,如果我们新扫描的数据小于堆顶的数据,那么我们就替换最小堆的堆顶数据,调整最小堆形成新的最小堆。最小堆可以用一个长为K大小的数组h模拟,对于结点h[i],其中父节点为h[i/2],儿子节点为:h[2*i+1]和h[2*i+2];*//************************************************************************//*n为要判断的数字,h为最小堆,k为topk 即最小堆维持的大小。*/void topK(int n,int *h,int K){    if(n<h[0])return;    int p = 0;    int q = 0;    h[0] = n;    while(p < K)    {        q = 2*p +1;        if (q >= K) break;        if (h[p] < h[q] && h[p] < h[q+1])break;        if (h[2*p+1] > h[2*p+2] ) q++;        int tem = h[q];        h[q] = h[p];        h[p] = tem;        p = q;    }}

 

简单的topK问题