如題,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;
}
結果如下圖:
舉個例子:
有一個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大小的情況,我們需要具體再細分下去,具體如何我們可以分情況討論。