Chinaunix首页 | 论坛 | 博客
  • 博客访问: 570432
  • 博文数量: 97
  • 博客积分: 5090
  • 博客等级: 大校
  • 技术积分: 969
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-01 14:56
文章分类

全部博文(97)

文章存档

2011年(1)

2009年(1)

2008年(14)

2007年(37)

2006年(44)

我的朋友

分类: C/C++

2006-03-24 12:53:51

下面是对磁盘文件记录进行归并排序,刚开始我还编译成功了,只是排序排不好,反而把记录全弄没了,后来我把程序不知道怎么动了一下,接着就编译出错,按照提示,始终找不出错误,麻烦大家帮忙看一下,不胜感激!
 
源程序如下(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;
}

       

         
阅读(1806) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~