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

  • 相关阅读:
    进程池,线程池,协程,gevent模块,协程实现单线程服务端与多线程客户端通信,IO模型
    线程相关 GIL queue event 死锁与递归锁 信号量l
    生产者消费者模型 线程相关
    进程的开启方式 进程的join方法 进程间的内存隔离 其他相关方法 守护进程 互斥锁
    udp协议 及相关 利用tcp上传文件 socketserver服务
    socket套接字 tcp协议下的粘包处理
    常用模块的完善 random shutil shevle 三流 logging
    day 29 元类
    Django入门
    MySQL多表查询
  • 原文地址:https://www.cnblogs.com/oldtab/p/4437522.html
Copyright © 2011-2022 走看看