解决一个题目。关于结构体与链表的操作

有初学者给我发了一个题目,求助我解决。

题目如下:

其实哥也不会C,但就是有一颗热心肠。于是果断研究起。

最后解决如下:

先上效果图

附上代码

// LinkListDemo.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <STDLIB.H>
# define LEN sizeof(struct examinee) //结构体长度

//考生结构体
struct examinee{
    int id; //考生编号
    char name [20];//考试姓名
    int score;//课程成绩
    struct examinee *next;//指针域
};
int n;//链表的长度

struct examinee *createE();//创建链表的函数声明。
void print(struct examinee *head);//打印链表的函数声明
struct examinee *sort(struct examinee *head);//排序链表的函数声明


int main(int argc, char* argv[])
{
    //printf("Hello World!
");

 printf("欢迎来到考试系统。请输入考试信息。
输入必须按照 编号 姓名 成绩格式,例如1 吴文付 12
");
  printf("如果输入的考生编号如果小于零,则停止输入并输出结果
");

         struct examinee *head= createE();
         printf("按照考试编号排序前
");
        print(head);
        printf("按照考试编号排序后
");
        struct examinee *head2 = sort(head);
        print(head2);
        //计算平均数
        int total = 0;//成绩总分
        int num = 0;//考试数量
        int top =0;//成绩最高分
        int last =0;//成绩最低分
        struct examinee *p1;
        p1 = head2;
        while(p1 != NULL){
            total += p1->score;
            num++;

            if(top == 0){
                top = p1->score;
            }
            
            //发现更大的分数,则取当前的分数
            if(top < p1->score){
                top = p1->score;
            }
            
            //初始化最小分数。
            if(last == 0){
                last = p1->score;
            }    

            //发现更小的分数。则取当前的分数
            if(last > p1->score){
                last = p1->score;
            }

            p1 = p1->next;
        }
        printf("平均分为%d,最高分为%d,最低分为%d
",total/num,top,last);

        

        
    return 0;
}

//创建链表
struct examinee *createE(){

    struct examinee *head,*p1,*p2;
    n=0;
    p1 = (struct examinee *)malloc(LEN);//分配内存空间
    
    scanf("%d %s %d",&p1->id,p1->name,&p1->score); //通过键盘输入给第一个节点赋值。

    head = NULL;//建立空链。
    //如果id大于0.则一直循环。
    while(p1->id > 0){
        n++;
        if(n == 1 ){ //节点数量为1。则当前节点就是链头
        head = p1;
        }else{ //如果节点数量大于1.则插入到链尾。
            p2->next = p1;
        }

        p2= p1;//移动指针p2
        p1 = (struct examinee *)malloc(LEN);//继续分配内存空间
        scanf("%d %s %d",&p1->id,p1->name,&p1->score); //通过键盘给下一个节点赋值
        
    }

    //数据输入结束。设置链尾
    p2->next = NULL;
    return head;//返回链头
}

//输出链表的数据
void print(struct examinee *head){
    struct examinee *p;
    p=head;
    while(p != NULL){
        printf("编号为%d姓名为%s成绩为%d
",p->id,p->name,p->score);
        p = p->next;
    }


}

//根据编号进行排序
struct examinee *sort(struct examinee *head){
     struct examinee *endpt;      //控制循环比较
    struct examinee *p;          //临时指针变量
    struct examinee *p1,*p2;

    p1 = (struct examinee *) malloc (LEN);
    p1->next = head;           //注意增加一个节点,放在第一个节点的前面,主要是为了便于比较。因为第一个节点没有前驱,我们不能交换地址
    head = p1;                   //让head指向p1节点,排序完成后,我们再把p1节点释放掉

    for (endpt = NULL; endpt != head; endpt = p)    
    {
        for (p = p1 = head; p1->next->next != endpt; p1 = p1->next)
        {
            if (p1->next->id > p1->next->next->id)    //如果前面的节点键值比后面节点的键值大,则交换
            {
                p2 = p1->next->next;      
                p1->next->next = p2->next;      
                p2->next = p1->next;     
                p1->next = p2;      
                p = p1->next->next;   
            }
        }
    }

    p1 = head;                //把p1的信息去掉
    head = head->next;        //让head指向排序后的第一个节点
    free (p1);            //释放p1
    p1 = NULL;            //p1置为NULL,保证不产生“野指针”,即地址不确定的指针变量

    return head;
}
原文地址:https://www.cnblogs.com/jsRunner/p/4500735.html