标签:
数据继续增加,麻烦很多。下面给出一个方案:
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;
}
//----------------------
#define i1K 1024
#define i1M i1K* i1K
#define BlockSize (100*i1M)
void GetTopK(int sele, int All)
{
double times[3]= { GetTickCount() };
int *Data0= new int[sele], *Data1= new int[BlockSize], File0Number;
String path= "D:\\", name= "inFile.dat";
//第一步,打开或文件不存在时,做出随机数据文件。
if(File0Number= open(String(path+ name).c_str(), 0), File0Number== -1)
{
File0Number= creat(String(path+ name).c_str(), 2);
for(int all= All, size= BlockSize; all> 0; all-= size) //减去做好的
for(int i= 0; i<= size; i++)
if(i== size)
_rtl_write(File0Number, Data1, min(size, all)); //写出一块数据
else
Data1[i]= random(BlockSize); //得随机数
lseek(File0Number, 0, SEEK_SET); //回文件首
}
times[0]= GetTickCount()- times[0];
times[1]= GetTickCount();
//第二步,取出数据。
_rtl_read(File0Number, Data0, sele);
for(int i= (sele- 2)/ 2; i>= 0; i--)
shift(Data0, i, sele); //建堆
for(int i, size= 1; size> 0; )
for(size= _rtl_read(File0Number, Data1, BlockSize), i= 0; i< size; i++)
if(Data0[0]> Data1[i]) //小值
Data0[0]= Data1[i], shift(Data0, 0, sele); //加小值,再成堆
times[1]= GetTickCount()- times[1];
times[2]= GetTickCount();
//第三步,验证()
//略
times[2]= GetTickCount()- times[2];
delete []Data0;
delete []Data1;
}
它先判断是否有原始数据文件。无则创建并写入随机数据。
再取出sele个数据。建最大堆。继续读出数据块。并逐步挑出最小数。
程序看起来,还是很简单的。但,有两个问题:
1、int 数的表达范围,只有二十亿。程序应该考虑数的表达范围问题了。
2、验证有麻烦:之前,我们①用标准排序与结果比较。②还可用结果中的最大数,与取值后余下的数做比较,要是得到这个最大数都小于或等余下的数,就证明结果是正确的。现在,数太多,没法用标准排序。而取数后的数,还是保留在原始数据中。也就不能用法②。
暂时就这样了。待想出验证办法再说。
如何在很大数量级的数据中(比如1个亿)筛选出前10万个最小值?之七
标签:
原文地址:http://www.cnblogs.com/oldtab/p/4465890.html