有初学者给我发了一个题目,求助我解决。
题目如下:
其实哥也不会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; }