TOP-K排序算法,从海量不重复数据中找出最大/小的K个数

如题,TOP-K排序的主要功能是找出一堆不重复数据中的最小或最大的几个数,此处我们介绍这种类型题目的某种解法:

最大最小堆,最大堆结构里面的每一个数不都是小于root的值么?和我们要解决的问题很像。由此,我们可以构造一个堆,并且用它来存储我们需要找的那几个数。有这么一个动态flash就很好地揭示了其中关系: top-k动画演示

关于什么是堆在此就不做介绍了,但注意,此处所用的的最大最小堆和数据结构的推排序的堆有区别,不再赘述。下面给出一个例子来供参考:(C++代码)

#include<stdio.h>
#include<iostream>
using namespace std;
struct min_heap{
    min_heap(int n){
        this->size=n;
        for(int i=0;i<size;i++) heap[i]=-1;
    }
    int size;
    int heap[100];
    void add(int n){
        if(n<=heap[0]) return;
        int tem=0;
        heap[0]=n;
        while(tem<size){
            if(2*tem+1>=size) break;
            if(2*tem+2>=size&&heap[tem]<heap[2*tem+1]) break;
            if(2*tem+2>=size&&heap[tem]>heap[2*tem+1]){
                int chan=heap[tem];
                heap[tem]=heap[2*tem+1];
                heap[2*tem+1]=chan;
                break;
            }
            if(heap[tem]<heap[2*tem+1]&&heap[tem]<heap[2*tem+2]) break;
            else{
                int min= 2*tem+1;
                if(heap[min]>heap[2*tem+2]) min=2*tem+2;
                int chan=heap[tem];
                heap[tem]=heap[min];
                heap[min]=chan;
                tem=min;
            }
        }
    }
    void print(){
        for(int i=0;i<size;i++){
            if(heap[i]>0) cout<<heap[i]<<" ";
        }
        cout<<endl;
    }

};


//测试用例:
int main(){
    int a[12]={145436,2234,113,4,5,6,7,8,9,23,45,67};
    min_heap* test=new min_heap(4);
    for(int i=0;i<12;i++){
        test->add(a[i]);
        test->print();
    }
    test->print();
    return 0;
}
 
 结果如下图:
TOP-K排序算法,从海量不重复数据中找出最大/小的K个数_第1张图片




举个例子:

有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M。返回频数最高的100个词。

大数据的题有这么一个模式:先hash缩小,然后hash统计,然后排序。

此题,内存只有2××20b,数据共2××30b,假设每个词皆2××4b,我们可以推出内存一次可以存2××16个数据,总数据2××26个,我们可以hash%1024分成1024堆(hash等于某值就存储之),每堆大小大约1M,在1024堆里面统计词频,然后用上述K-tops求出结果。

当然,也有可能出现某堆不止1m大小的情况,我们需要具体再细分下去,具体如何我们可以分情况讨论。


你可能感兴趣的:(TOP-K排序算法,从海量不重复数据中找出最大/小的K个数)