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

单向链表

用单向链表,还更麻烦。因为,插入时,必须修改插入点的前一节点的后续值。因此,做查找时,临时维护一个前趋。也不知道有没好处。代码如下:

//----------------------                                        //单向链
struct SOutOne
{
  int value,      next;
};
void SortLinkOne(int Data[], int m, int n, SOutOne Out[])
{
  for(int count= 0, head= 0, end= 0, i= 0; i<= m; i++)
    if(i== m)                                                   //结束
    {
      if(head> 0)
      {
        SOutOne t= Out[0];
        Out[0]= Out[head], Out[head]= t;                        //链首换到0
        for(int j= 0; j< count; j++)
          if(j!= end && Out[j].next== 0)
            Out[j].next= head;
      }
    }
    else if(count== n && Data[i]>= Out[end].value)              //无效数据
      continue;
    else
    {
      for(int end1, see1, see= head, j= 0; ; see1= see, see= Out[see].next, j++)
      {
        if(j== count)                                           //追加
        {
          if(Out[count].value= Data[i], count> 0)
            Out[end].next= count,   end= count;                 //新尾
          count++;
          break;
        }
        else if(Data[i]< Out[see].value)                        //插入
        {
          end1= count== n? end: count;
          if(Out[end1].value= Data[i], count< n || see!= end1)
          {
            Out[end1].next= see;
            if(see== head)
              head= end1;
            else
              Out[see1].next= end1;
            if(count< n)
              count++;
            else
              for(int lim= n- 1, see= head, j= 0; ; see= Out[see].next, j++)
                if(j== lim)
                { end= see; break; }
          }
          break;
        }
      }
    }
}

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);

  SOutOne*Out= new SOutOne[n+ 1];
err:
  SortLinkOne(Data, m, n, Out);
  ShowTime("单向链处理用时", tms);
  for(int see= 0, i= 0; i<= n; see= Out[see].next, i++)
    if(i== n)
    { ShowMessage("找好");  break; }
    else if(DataSort[i]!= Out[see].value)
    { ShowMessage("出错");  goto err; }

  delete []DataSort;
  delete []Data;
  delete []Out;
}

  一亿取十万,用时:2794秒。你没看错。约是折半查找的十倍。链表,在这,空间用得多,速度还很慢。下一步,看看堆排序。据说,堆排序特别适合这里使用。

posted @ 2015-04-18 15:49  汇铁  阅读(272)  评论(0编辑  收藏  举报