如何在很大数量级的数据中(比如1个亿)筛选出前10万个最小值?之五

堆处理:

    

void shift(int data[], int i, int length)                       
{
  for(int c; c= i* 2+ 1, c< length; )
    if(c+= c+ 1< length && data[c]< data[c + 1], data[i]<= data[c])
      swap(data[c], data[i]),     i= c;
    else
      break;
}
void SortHeap(int data[], int m, int n)
{
  for(int i=(n- 2)/ 2; i>= 0; i--)
    shift(data, i, n);                                          //建堆
  for(int i= n; i< m; i++)
    if(data[i]< data[0])                                        //加小值
      data[0]= data[i],           shift(data, 0, n);            //再建堆
  for(int n1= n-1, i= 0; i< n; i++)
    swap(data[0], data[n1- i]),   shift(data, 0, n1- i);        //堆转队列
}

  提供数据、调用堆排序、正确性验证及计时的代码:

void ShowTime(String caption, Double &tms)
{
  ShowMessage(String(caption+ "   "+ (GetTickCount()- tms)/1000)+ "秒");
  tms= GetTickCount();
}
void control(int n)
{
  int m= n< 9? n+ 2: n* pow(10, 3);                             //小数据调试
  double tms= GetTickCount();
  int *Data= new int[m], *DataSort= new int[m];
  for(int i= 0; i< m; i++)                                      //得随机数
    DataSort[i]= Data[i]= random(m);
  ShowTime("制造随机数用时", tms);
  sort(DataSort, DataSort+ m);
  ShowTime("标准排序用时", tms);
err:
  int k= n;
  SortHeap(Data, m, k);
  ShowTime("排序用时", tms);
  for(int k= n, i= 0; i<= k; i++)
    if(i== k)
      ShowMessage("取值正确");
    else if(DataSort[i]!= Data[i])
    { ShowMessage("取值出错"); goto err; }

  delete []DataSort;
  delete []Data;
}

  一亿取十万用时:2.19秒。真的够快。体现了算法的威力与魅力。

按题意,不排序也是可以的。那样,只在1.6秒。

原文地址:https://www.cnblogs.com/oldtab/p/4439510.html