链表习题

来源:互联网 发布:科比布莱恩特生涯数据 编辑:程序博客网 时间:2024/06/05 20:07

在这两个数据文件中,1.dat文件中的用餐记录数据已经按照用餐金额进行了增序排列。请按要求完成如下操作:

 

1.        编写一个函数,读取1.dat文件中的所有用餐记录数据,并构建一个用餐记录链表。

2.     编写一个函数,在屏幕上显示第1步中生成的用餐记录链表中的所有数据,要求每行输出1条记录,显示内容和格式要求如下:

学生学号

占25列,左对齐

用餐金额

占10列

左对齐,小数点后保留2位

SD13079006

5.50

SD11039029

9.00

……

 

上述示意内容中斜体和线条部分仅用于说明题意的说明信息,不需要实际显示出来。

3.        编写一个函数,依次读取2.dat文件中的各用餐记录数据,并将读取到的每个各用餐记录数据插入到上述第1步所生成的链表中,要求插入后仍然保证链表各结点按照用餐金额的增序排列然后在屏幕上显示用餐记录链表中的所有数据,格式要求与第2步相同。

4.        编写一个函数,求出第3步中生成的链表中学生用餐记录中用餐金额的平均值。在main函数中输出所求得的平均值。

5.        编写一个函数,将第3步中生成的链表中的用餐记录数据按照学生学号进行合并处理。也就是说中同一学生的用餐金额累加后合并到该学生在链表中所出现的第1个结点中去、并将后面结点中该学生的记录数据删除。具体如下图所示,下图演示了一个合并前后的例子。

6.        编写一个函数,将第5步生成的链表中的所有用餐数据输出到D盘根目录下的文本文件res.txt中,格式要求与第2步相同。

编写一个函数,删除建立的链表。



//文件数据读取结构体定义
struct Dining
{
        char StudentID[15];        //学生学号
        float Price;            //用餐金额(元)
};

//链表结点结构体定义
typedef struct DiningNode
{
        char StudentID[15];        //学生学号
        float Price;            //用餐金额(元)

        struct DiningNode *Next;
}TagNode;

TagNode * append_node(TagNode * head,TagNode* temp)  //不带哨兵节点
{
    TagNode* p=head;
    if(head==NULL){
        head=temp;
    }
    else{
        while(p->Next!=NULL){  //找到尾节点
            p=p->Next;
        }
        p->Next=temp;
        temp->Next=NULL;
    }

    return head;
}

TagNode * Create_List(char* filename){
    FILE* fp;
    TagNode* head=NULL;
    TagNode* p;
    TagNode temp;
    fp=fopen(filename,"rb");
    if(fp==NULL){
        printf("file error!\n");
    }

    while(fread(&temp,sizeof(struct Dining),1,fp)==1){
        p=(TagNode*)malloc(sizeof(TagNode));
        *p=temp;
        p->Next=NULL;
        head=append_node(head,p);
    }

    fclose(fp);

    return head;
}


void insert_node(TagNode* head,TagNode* temp)
{
    TagNode* p,q;
    if(head==NULL) head=temp;
    if(head->Price>temp->Price){
        temp->Next=head;
        head=temp;
    }
    else{
        p=head;
        while(p->Next!=NULL){
            if(p->Price<=temp->Price && p->Next->Price>=temp->Price){
                temp->Next=p->Next;
                p->Next=temp;
                break;
            }
            else p=p->Next;
        }
        if(p->Next==NULL) p->Next=temp;
    }
}

void Add_Nodes(TagNode* phead,char* filename)
{
    FILE* fp=fopen(filename,"rb");
    TagNode temp;
    TagNode* p;

    if(fp==NULL) printf("file error!\n");
    while(fread(&temp,sizeof(struct Dining),1,fp)==1){
        p=(TagNode*)malloc(sizeof(TagNode));
        *p=temp;
        p->Next=NULL;
        insert_node(phead,p);
    }

    fclose(fp);
}

float  Calcuate_Average(TagNode* phead)
{
    TagNode* p=phead;
    float sum=0;
    int count=0;
    if(phead==NULL) printf("no record!\n");
    while(p){
        sum+=p->Price;
        count++;
        p=p->Next;
    }
    return sum/(float)count;
}

void Combine_Nodes(TagNode* phead)
{
    TagNode* p,*q,*k;
    p=q=k=phead;
    while(p){
        q=p->Next;
        k=p;
        while(q){
            if(strcmp(q->StudentID,p->StudentID)==0){
                p->Price=p->Price+q->Price;
                k->Next=q->Next;
                free(q);
                q=k->Next;
            }
            else{
                k=q;
                q=q->Next;
            }
        }
        p=p->Next;
    }
}

void Display_List(TagNode* phead){
    if(phead==NULL){
        printf("phead error!");
        return;
    }
    else{
        while(phead!=NULL){
            printf("%-25s%-10.2f\n",phead->StudentID,phead->Price);
            phead=phead->Next;
        }
    }
}

void Output_List(char* filename,TagNode* phead)
{
    FILE* fp=fopen(filename,"w");
    TagNode* p=phead;
    if(fp==NULL) printf("file error!\n");
    while(p){
        fprintf(fp,"%-25s%-10.2f\n",p->StudentID,p->Price);
        p=p->Next;
    }
    fclose(fp);
}

void Free_List(TagNode* phead)
{
    TagNode* p;
    p=phead;
    while(phead){
        phead=p->Next;
        free(p);
        p=phead;

    }
}

int main()
{
    TagNode *phead;             // 指向链表的头结点
    float avg;                 // 存放链表中结点的平均值

    //===创建链表并显示链表=======
    puts("1.dat文件读取后的学生就餐记录链表为:");
    phead = Create_List("D:\\1.dat");   // 创建链表
    Display_List(phead);             // 显示链表

    //===读取2.dat文件中的数据,并将其添加到学生就餐记录链表中=====
    puts("2.dat文件中的数据读取并添加完成后的学生就餐记录链表为:");
    Add_Nodes(phead,"D:\\2.dat");             // 逆序链表
    Display_List(phead);             // 显示链表

    //===找出平均值====
    avg = Calcuate_Average(phead);   // 找出平均值
    printf("链表中用餐金额的平均值为:%10.2f\n", avg);
    //===链表结点合并处理===    
    Combine_Nodes(phead);         // 对链表进行结点合并处理
    puts("结点合并处理后的链表为:");
    Display_List(phead);

    //===输出链表中的就餐记录数据到文件中====
    Output_List("D:\\res.txt",phead);   // 输出链表中的就餐记录数据到res.txt文件

    //====释放链表======
    Free_List(phead);

    return 0;
}