用堆解决Top-K问题

Top-K问题:一般是求数据集合中前k个最大或最小的元素,一般数据量很大。

比如专业排名的前十名,全国财富榜的前一百位富豪,一个游戏最强的前十名玩家等等。

对于Top-k问题,最容易想到的方法就是排序,但是当数据量过大时,数据很难同时加载到内存中,所以排序并不适合解决Top-k问题。最适合的方法是用堆进行解决。

基本思路:

1.用数据集合中的前K个元素建堆。(若是求最大的K个元素则建小堆;求最小的K个元素则建大堆)

2.用数据集合中剩余的N-K个元素依次与堆顶元素进行比较,若满足预设条件则替换掉堆顶元素,并对堆进行向下调整使之重新成为堆。将剩余的N-K个元素都比较完,堆中的K个元素就是最大/小的K个元素。

代码如下:

//交换函数
void Swap(int*p1,int*p2)
{
    int tmp=*p1;
    *p1=*p2;
    *p2=tmp;
}
 
 //向下调整函数
void AdjustDown(int*a,int n,int parent)
{
    int child = parent*2+1;
    while(child < n)
    {
       if(child+1<n && a[child+1]<a[child])
       {
          child++;
       }
       if(a[child]<a[parent])
       {
          Swap(&a[parent],&a[child]);
          parent=child;
          child=parent*2+1;
       }
       else
       {
          break; 
       }
    }
}



int*getLeastNumbers(int*arr,int arrSize,int k,int*returnSize)
{
  *returnSize=k;
  if(k==0)
  {
    return NULL;
  }
//开辟可容纳K个元素的数组并调整成堆
  int i=0;
  int*heap=(int*)malloc(sizeeof(int)*k);
  for(i=0;i<k;i++)
  {
    heap[i]=arr[i];
  } 
  for(i=(k-1-1)/2;i>=0;i--)
  {
    AjustDown(heap,k,i);
  }
//将剩余的arrSize-k个元素分别与堆顶元素进行交换,若大于堆顶元素,则进行交换,并调整堆。
  for(i=k;i<arrsize;i++)
  {
    if(arr[i]>heap[0])
    {
      Swap(&arr[i],&heap[0]);
    }
    AjustDown(heap;k;0);
  }
  return heap;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值