大容量排序算法:
前言:
在内存容量有限,并且栈容量有限的情况下,我们是不能声明如int array[10000000000]的数的,那我们应该怎么排序大容量的数据呢、本文给数了一种方法,在VC++6.0中编译通过。
程序如下:
1.生成随机数文件
2.排序该文件
1)
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<stdlib.h>
#include<time.h>
typedef struct tagDATAHEADER//文件头
{
long datalength;//数据长度
long dataoffset;//数据偏移量
char author[20];//作者,也就是我了
char time[50];//生成随机数文件的时间
char remain[432];//保留
}Dataheader;
int main(void)
{
long i,num;
FILE *fp;
time_t ltime;
Dataheader dataheader;
printf("input data length:");
scanf("%ld",&dataheader.datalength);
dataheader.dataoffset=sizeof(dataheader)*10;
strcpy(dataheader.author,"YangCheng");
time( <ime );
strcpy(dataheader.time,asctime(gmtime(<ime)));
fp=fopen("sort.dat","wb");
if(fp==NULL)
{
printf("open file error!");
return -1;
}
if(fwrite(&dataheader,sizeof(dataheader),1,fp)!=1)
{
printf("write file error!");
return -1;
}
srand( (unsigned)time(NULL));
fseek(fp,dataheader.dataoffset,SEEK_SET);//注意偏移量
for(i=0;i<dataheader.datalength;i++)
{
num=rand()%10000;//生成随机数
if(fwrite(&num,sizeof(long),1,fp)!=1)
{
printf("write file error!");
return -1;
}
}
fclose(fp);
return 0;
}
2)
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<stdlib.h>
#include<time.h>
typedef struct tagDATAHEADER
{
long datalength;
long dataoffset;
char remain[512];
}Dataheader;
int main(void)
{
Dataheader dataheader;
long pre,next,i,j,num,offset;
FILE *fp1,*fp2,*fp;
offset=sizeof(long);
printf("\nSource Data:\n\n");//未排序时的数据
fp=fopen("sort.dat","rb");
if(fp==NULL)
{
printf("read error!");
return -1;
}
fread(&dataheader,sizeof(dataheader),1,fp);
fseek(fp,dataheader.dataoffset,SEEK_SET);
for(i=0;i<dataheader.datalength;i++)
{
fread(&num,sizeof(long),1,fp);
printf("%ld ",num);
}
fclose(fp);
fp1=fopen("sort.dat","rb+");
fp2=fopen("sort.dat","rb+");
if(fp1==NULL||fp2==NULL)
{
printf("read error!");
return -1;
}
for(i=0;i<dataheader.datalength-1;i++)//注意长度
{
fseek(fp1,dataheader.dataoffset,SEEK_SET);//注意偏移量
fseek(fp2,dataheader.dataoffset+offset,SEEK_SET);
for(j=0;j<dataheader.datalength-1;j++)
{
if(!feof(fp1)&&!feof(fp2))
{
fread(&pre,offset,1,fp1);
fread(&next,offset,1,fp2);
if(pre>next)//从小到大排序
{
fseek(fp1,-offset,SEEK_CUR );
fseek(fp2,-offset,SEEK_CUR );//注意指针的位置的改变
fwrite(&next,offset,1,fp1);
fwrite(&pre,offset,1,fp2);
fflush(fp1);
fflush(fp2);
}
}
}
}
fclose(fp1);
fclose(fp2);
printf("\n\nSorted Data:\n\n");//排完顺序后的数据
fp=fopen("sort.dat","rb");
if(fp==NULL)
{
printf("read error!");
return -1;
}
fread(&dataheader,sizeof(dataheader),1,fp);
fseek(fp,dataheader.dataoffset,SEEK_SET););//注意偏移量
for(i=0;i<dataheader.datalength;i++)
{
fread(&num,sizeof(long),1,fp);
printf("%ld ",num);
}
fclose(fp);
printf("\n");
return 0;
}
----------------解决方案--------------------------------------------------------
看起来很牛。。。。。。
偶是菜鸟慢慢看
----------------解决方案--------------------------------------------------------
大容量排序应该是用到外排序吧.
----------------解决方案--------------------------------------------------------
看了楼主的程序发现二个问题:
问题1.
dataheader.dataoffset=sizeof(dataheader)*10;
乘以10就有一点过,因为
typedef struct tagDATAHEADER//文件头
{
long datalength;//数据长度
long dataoffset;//数据偏移量
char author[20];//作者,也就是我了
char time[50];//生成随机数文件的时间
char remain[432];//保留
}Dataheader;
大约有0.5KB的大小.而你乘以10是相当于浪费了9个sizeof(dataheader)的空间
相当4.5KB的大小在文件中.作为一个程序员是不愿看到的.
完全可以乘以1就可以,不要为了担心数据的重叠.
问题2.
你在生成的文件时数据结构用这个
typedef struct tagDATAHEADER//文件头
{
long datalength;//数据长度
long dataoffset;//数据偏移量
char author[20];//作者,也就是我了
char time[50];//生成随机数文件的时间
char remain[432];//保留
}Dataheader;
而读取的时用另外一种数据结构
typedef struct tagDATAHEADER
{
long datalength;
long dataoffset;
char remain[512];
}Dataheader;
很显然,读取的时侯只有datalength和dataoffset能正确读取,
其它的成员就无能为力了.建议用同一种数据结构.
需要赞赏你的是
fflush(fp1); fflush(fp2);用得妙.
要不然,两个文件指针同时对文件的读写会造成数据紊乱.
----------------解决方案--------------------------------------------------------