下面是对磁盘文件记录进行归并排序,刚开始我还编译成功了,只是排序排不好,反而把记录全弄没了,后来我把程序不知道怎么动了一下,接着就编译出错,按照提示,始终找不出错误,麻烦大家帮忙看一下,不胜感激!
源程序如下(c语言描述):
#include
#include
/* 记录结构 */
struct stu
{
long ID;
int g;
};
/* b是一条记录所占的字节数 */
#define b sizeof(struct stu)
/* 下面这个函数是对fpa的第s~m,和m+1~t的两个有序记录进行两路归并 */
void FTwomerge(FILE *fpA, FILE *fpR, int s, int m, int t)
{
int i, j, k;
struct stu stu1, stu2;
for (i = m+1, k = s; s <= m && i <= t; ++k)
{
fseek(fpA, s*b, 0);
fread(&stu1, b, 1, fpA); /* 读第一个归并段的记录 */
fseek(fpA, i*b, 0);
fread(&stu2, b, 1, fpA); /* 读第二个归并段的记录 */
if (stu1.g <= stu2.g)
{
fseek(fpR, k*b, 0);
fwrite(&stu1, b, 1, fpR);
s++;
}
else
{
fseek(fpR, k*b, 0);
fwrite(&stu2, b, 1, fpR);
i++;
}
}
/* 对前一个归并段中存在的未归并的元素进行处理 */
for (j = s; j <= m; ++j, ++k)
{
fseek(fpA, j*b, 0);
fseek(fpR, k*b, 0);
fread(&stu1, b, 1, fpA);
fwrite(&stu1, b, 1, fpR);
}
/* 对后一个归并段中存在的未归并的元素进行处理 */
for (j = i; j <= t; ++j, ++k)
{
fseek(fpA, j*b, 0);
fseek(fpR, k*b, 0);
fread(&stu1, b, 1, fpA);
fwrite(&stu2, b, 1, fpR);
}
}
/* 把文件A进行一趟二路归并的算法 */
void FMergePass(FILE *fpA, FILE *fpR, int n, int len)
{
/* 把文件A中每个长度为len的有序表两两归并到文件R */
struct stu x; /* 临时变量,临时存储记录 */
int start_p, end_p;
start_p = 0;
while (start_p + len < n)
{
end_p = start_p + 2*len - 1;
if (end_p >= n)
end_p = n - 1;
FTwomerge(fpA, fpR, start_p, start_p + len - 1, end_p);
start_p = end_p + 1;
}
if (start_p < n)
{
for (; start_p < n; start_p++)
{
fseek(fpA, start_p*b, 0);
fseek(fpR, start_p*b, 0);
fread(&x, b, 1, fpA);
fwrite(&x, b, 1, fpR);
}
}
}
/* 采用归并排序的方法对文件A中的,每个有序子表长度为BlockSize的记录进行排序 */
void FMergeSort(FILE *fpA, int BlockSize)
{
/* 定义一个辅助文件 R*/
FILE *fpR;
struct stu x; /*临时变量,用来临时存储记录*/
int len, n, k;
k = 0;
len = BlockSize; /*有序子表长度*/
fseek(fpA, 0L, 2); //将文件A的指针移到文件的末尾
n = ftell(fpA) / b; /* n = 文件的记录条数 */
if ((fpR = fopen("temp.rec", "wb+")) == NULL)
{
printf("temp.rec can't open!\n");
exit(1);
}
while (len < n)
{
if (k == 0)
FMergePass(fpA, fpR, n, len);
else
FMergePass(fpR, fpA, n, len);
len = len*2;
k = 1-k;
}
if (k == 1)
{
for (k = 0; k < n; ++k)
{
fseek(fpA, k*b, 0);
fseek(fpR, k*b, 0);
fread(&x, b, 1, fpA);
fwrite(&x, b, 1, fpR);
}
}
fclose(fpR);
remove("temp.rec"); //删除磁盘上的临时文件
}
int main(int argc, char* argv[])
{
char num[20], ch;
struct stu s;
FILE *fpIN, *fpOUT, fpSORT;
if ((fpOUT = fopen("st1.rec", "ab")) == NULL)
{
printf("st1.rec can't open!\n");
exit(1);
}
do
{
printf("ID :");
gets(num);
s.ID = atol(num);
printf("Grade :");
gets(num);
s.g = atoi(num);
fwrite(&s, sizeof(s), 1, fpOUT);
printf("another(y/n)?");
ch = getchar();
getchar(); /* 接收回车 */
} while (ch == 'y');
fclose(fpOUT);
/*
if ((fpSORT = fopen("st1.rec", "wb+")) == NULL)
{
printf("st1.rec can't open!\n");
exit(1);
}
FMergeSort(fpSORT, 1);
fclose(fpSORT);
*/
if ((fpIN = fopen("st1.rec", "rb")) == NULL)
{
printf("st1.rec can't open!\n");
exit(1);
}
while (fread(&s, sizeof(s), 1, fpIN))
{
printf("%ld : %d\n", s.ID, s.g);
}
fclose(fpIN);
return 0;
}