• 如何在很大数量级的数据中(比如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秒。你没看错。约是折半查找的十倍。链表,在这,空间用得多,速度还很慢。下一步,看看堆排序。据说,堆排序特别适合这里使用。

  • 相关阅读:
    BZOJ3129/洛谷P3301方程(SDOI2013)容斥原理+扩展Lucas定理
    Dilworth定理
    字符串
    hash
    李超线段树(segment[HEOI2013]-洛谷T4097)
    连通数[JSOI2010]-洛谷T4306
    主席树
    splay
    树链剖分
    受欢迎的奶牛-洛谷2341
  • 原文地址:https://www.cnblogs.com/oldtab/p/4437522.html
Copyright © 2020-2023  润新知