如何在很大数量级的数据中(比如1个亿)筛选出前10万个最小值?之三
双向链表来处理:
双向链表,虽顺序比较,次数多。但插入不用移动数据。不知道这两者谁占上风。还是代码来运行一下吧。
代码如下:
#include <math.h>
#include <algorithm>
using namespace std;
struct SOutTwo { int value, next, pre; }; void SortLinkTwo(int Data[], int m, int n, SOutTwo Out[]) //双向链 { Out[0].pre= Out[0].next= 0; for(int head= 0, count= 0, end= 0, i= 0; i<= m; i++) if(i== m) //结束 { if(head> 0) { SOutTwo t= Out[0]; Out[0]= Out[head], Out[head]= t; //链首换到0 Out[Out[0].next].pre= Out[Out[0].pre].next= 0; Out[Out[head].next].pre= Out[Out[head].pre].next= head; } } else if(count== n && Data[i]>= Out[Out[head].pre].value) //无效数据 continue; else for(int see= head, j= 0; ; see= Out[see].next, j++) { if(j== count) //追加 { if(Out[count].value= Data[i], count> 0) { Out[Out[head].pre].next= count; Out[count].pre= Out[head].pre; Out[count].next= head; Out[head].pre= count; } count++; break; } else if(Data[i]< Out[see].value) //插入 { end= count== n? Out[head].pre: count; if(count== n && see!= end) //删除end节 Out[Out[end].next].pre= Out[end].pre, Out[Out[end].pre].next= Out[end].next; if(Out[end].value= Data[i], count< n || see!= end) { Out[Out[see].pre].next= end; Out[end].pre= Out[see].pre; Out[end].next= see; Out[see].pre= end; if(see== head) head= Out[see].pre; count+= count< n; } 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); SOutTwo*Out= new SOutTwo[n+ 1]; SortLinkTwo(Data, m, n, Out); ShowTime("双向链处理用时", tms); for(int see= 0, i= 0; i<= n; see= Out[see].next, i++) if(i== n || DataSort[i]!= Out[see].value) { ShowMessage(i== n? "找好": "出错"} delete []DataSort; delete []Data; delete []Out; }
一亿取十万,用时:339.49秒。比折半差,但接近。增加了不少空间。没得好处。细想,维护链的前趋与后续,都要增加赋值。因此想,单链是不是会好点?下一次,用单链。