学生管理系统(C语言综合链表实现)
题目:定义单向链表类型StuLink,链表结点包含xh、xm、cj、dj、mc、nxet六个数据项,分别代表学生的学号、姓名、成绩、等级、名次和指向下一个结点的指针,其中:学号、姓名、成绩是输入项,等级、名次是计算项。请按如下功能要求设计一个学生成绩管理程序,编程要求:
⑴ 设计main函数(10分):建立一个菜单系统,调用Creat_Link函数建立一个StuLink类型的学生链表;调用Insert_Node函数在链表尾插入一个新结点;调用Edit_Node函数修改链表中指定学号的结点;调用Delete_Node函数删除链表中指定学号的结点;调用Query_Node函数查询链表中指定学号的结点并显示查询结果;调用Rank_Link函数计算学生链表中每个学生的名次;调用Analysis_Link函数统计并返回各等级人数;调用Output_Link函数按指定数据项的顺序【学号(升序),或者,成绩(降序)】输出学生成绩表、各等级人数。
⑵ 设计Creat_Link函数(10分):建立一个StuLink类型的学生链表,返回链表头指针。每个链表结点代表一个学生信息,要求输入学号、姓名和成绩,其中:学号从1开始按递增1自动生成,成绩必须在[0,100]区间的整数,当输入成绩为-1时,表示输入结束。
⑶ 设计Insert_Node函数(10分):在链表尾插入一个新结点。新结点的学号是链表中最大学号加1,姓名和成绩从键盘输入(注意:成绩必须在[0,100]区间的整数),根据成绩计算等级。注意:插入结点会导致链表中各结点名次的变化。
⑷ 设计Edit_Node函数(10分):修改链表中指定学号的结点(注意:学号不能修改,成绩必须在[0,100]区间的整数)。注意:当修改成绩时会导致等级和名次的变化。
⑸ 设计Delete_Node函数(10分):删除链表中指定学号的结点。注意:删除操作需要重新计算链表中各结点的名次。
⑹ 设计Query_Node函数(10分):查询链表中指定学号的结点,并显示查询结果。
⑺ 设计Rank_Link函数(10分):计算学生链表中每个学生的名次。名次规则:按成绩降序排名,从第1名开始依次排名,若出现并列名次,则名次需要叠加。例如,若出现5个并列第1名,则没有第2名,下一个名次是第6名,依此类推。
⑻ 设计Analysis_Link函数(10分):统计并返回各等级人数。等级标准:
A:90及以上 B:80及以上 C:70及以上 D:60及以上 E:60以下
⑼ 设计Sort_Link函数(10分):按指定数据项的顺序【学号(升序),或者,成绩(降序)】对学生链表进行排序。
⑽ 设计Output_Link函数(10分):按指定数据项的顺序【学号(升序),或者,成绩(降序)】输出学生成绩表、各等级人数。学生成绩表每行输出一个学生信息(依次为学号、姓名、成绩、等级和名次,各项间以1个空格隔开),各等级人数分行输出。
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
struct StuLink
{
int xh;
char xm[20];
int cj;
char dj;
int mc;
struct StuLink *next;
};
struct StuLink* Creat_Link(struct StuLink* head); //建立一个StuLink类型的学生链表
struct StuLink* Insert_Node(struct StuLink * head); //在链表尾插入一个新结点
struct StuLink* Edit_Node(struct StuLink* head); //修改链表中指定学号的结点
struct StuLink* Delete_Node(struct StuLink* head); //删除链表中指定学号的结点
struct StuLink* Rank_Link(struct StuLink* head); //计算学生链表中每个学生的名次
void Query_Node(struct StuLink* head); //查询链表中指定学号的结点
void Analysis_Link(struct StuLink *head); //统计并返回各等级人数
void Sort_Link(struct StuLink* head,int n); //按指定数据项的顺序(学号升序)(成绩降序)进行排序
void Output_Link(struct StuLink *head,int n) //按指定数据项的顺序(学号升序)(成绩降序)输出成绩
void display_by_xh(struct StuLink* head); //将学生节点按学号升序排序
void display_by_cj(struct StuLink* head); //将学生节点按学成绩降序排序
void swap(struct StuLink* p1, struct StuLink* p2); //交换两个节点的值
int main()
{
int n;
struct StuLink *head=NULL;
while(1)
{
system("cls");
printf(" 主菜单—学生成绩管理 \n");
printf(" =============================\n");
printf("|1-创建链表 2-链表维护 |\n");
printf("|3-计算排序 4-统计分析 |\n");
printf("|5-报表输出 0-退出 |\n");
printf(" =============================\n");
printf(" 请输入菜单编号(0-5):");
scanf("%d",&n);
while(!(n==1 || n==2 || n==3 || n==4 || n==5 || n == 0 ) )
{
printf("输入错误,请重新输入");
scanf("%d",&n);
}
if(n==0)
{
printf("感谢使用成绩管理系统,谢谢!");
break;
}
switch(n)
{
case 1:
head=Creat_Link(head);
fflush(stdin);
printf("\n按回车键继续\n");
getchar();
break;
case 2:
while(1)
{
system("cls");
printf(" 二级菜单—链表维护管理\n");
printf(" ======================\n");
printf("| 1-添加一个学生信息 |\n");
printf("| 2-修改一个学生信息 |\n");
printf("| 3-删除一个学生信息 |\n");
printf("| 4-查询一个学生信息 |\n");
printf("| 0-退回上级菜单 |\n");
printf(" ======================\n");
printf(" 请输入菜单编号(0-4):");
scanf("%d",&n);
while(!(n==1 || n==2 || n==3 || n==4 || n==5 || n == 0 ))
{
printf("输入错误,请重新输入");
scanf("%d",&n);
}
if(n==0)break;
else
switch(n)
{
case 1:head=Insert_Node(head);break;
case 2:head=Edit_Node(head);break;
case 3:head=Delete_Node(head);break;
case 4:Query_Node(head);break;
}
fflush(stdin);
printf("请按回车键继续");
getchar();
}
break;
case 3:
while(1)
{
system("cls");
printf(" 二级菜单—计算排序管理\n");
printf(" ======================================\n");
printf("| 1-计算学生名次 2-按学号升序排序 |\n");
printf("| 3-按成绩降序排序 0-返回上级菜单 |\n");
printf(" ======================================\n");
printf(" 输入菜单编号(0-3): ");
scanf("%d",&n);
while(!(n==1 || n==2 || n==3 || n == 0 ) )
{
printf("输入错误,请重新输入");
scanf("%d",&n);
}
if(n==0)break;
else
switch(n)
{
case 1:head=Rank_Link(head),display_by_xh(head);break;
case 2:Sort_Link(head,2);break;
case 3:Sort_Link(head,3);break;
}
fflush(stdin);
printf("请按回车键继续");
getchar();
}
break;
case 4:
Analysis_Link(head);
fflush(stdin);
printf("请按回车键继续");
getchar();
break;
case 5:
while(1)
{
system("cls");
printf(" 二级菜单—报表输出管理\n");
printf(" ========================================\n");
printf("| 1-学号升序 2-成绩降序 0-返回上级菜单 |\n");
printf(" ========================================\n");
printf(" 输入菜单编号(0-2): ");
scanf("%d",&n);
while(!(n==1 || n==2 || n==3 || n == 0 ) )
{
printf("输入错误,请重新输入");
scanf("%d",&n);
}
if(n==0)break;
else
switch(n)
{
case 1:Output_Link(head,1);break;
case 2:Output_Link(head,2);break;
}
fflush(stdin);
printf("请按回车键继续");
getchar();
}
}
}
return 0;
}
struct StuLink* Creat_Link(struct StuLink* head)
{
struct StuLink *p1=NULL, *p2=NULL;
int score=0,i=1;
char name[20];
printf("请输入学生姓名和成绩\n");
printf("(输入成绩为-1结束输入):\n");
while(1)
{
scanf("%s%d",name,&score);
while(!(score>=0 && score<=100) && score != -1)
{
printf("输入成绩错误,请重新输入:");
scanf("%s%d",name,&score);
}
if(score == -1)break;
if((p1=(struct StuLink *)malloc(sizeof(struct StuLink)))==NULL)
{
printf("error");
exit(0);
}
p1->next=NULL; //当链表只有一个结点时,head的next为NULL
p1->xh=i++; //创建链表时学号自动生成
strcpy(p1->xm,name);
p1->cj=score;
if(score>=90) p1->dj='A';
else if(score>=80 && score<90) p1->dj='B';
else if(score>=70 && score<80) p1->dj='C';
else if(score>=60 && score<70) p1->dj='D';
else p1->dj='E';
if(i==2)head=p1;
else p2->next=p1;
p2=p1;
}
head=Rank_Link(head);
printf("\n名次计算结果和链表创建结果如下:\n");
display_by_xh(head);
return head;
}
struct StuLink* Insert_Node(struct StuLink * head)
{
struct StuLink *p1=head,*p0=NULL,*p2=NULL;
char name[20];
int score;
printf("请输入姓名和成绩:\n");
scanf("%s%d",name,&score);
while(!(score>=0 && score<=100) )
{
printf("输入成绩错误,请重新输入");
scanf("%s%d",name,&score);
}
if((p0=(struct StuLink *)malloc(sizeof(struct StuLink)))==NULL)
{
printf("error");
exit(0);
}
strcpy(p0->xm,name);
p0->cj=score;
if(score>=90) p0->dj='A';
else if(score>=80 && score<90) p0->dj='B';
else if(score>=70 && score<80) p0->dj='C';
else if(score>=60 && score<70) p0->dj='D';
else p0->dj='E';
p0->next=NULL;
if(p1==NULL)
{
p0->xh=1; //若链表为空,学号为1
head=p0,head->next=NULL;
}
else
{
while(p1!=NULL) //若不为空
{
p2=p1;
p1=p1->next;
}
p0->xh=p2->xh+1; //新成学号为最大学号加一
p2->next=p0;
}
head=Rank_Link(head);
printf("\n名次计算结果和链表插入结果如下:\n");
display_by_xh(head);
return head;
}
struct StuLink* Rank_Link(struct StuLink* head)
{
int i,count=0;
struct StuLink* p1=NULL,*p2=NULL;
for(p1=head;p1!=NULL;p1=p1->next)
{
for(p2=head;p2!=NULL;p2=p2->next)
{
if(p1->cj < p2->cj)count++;
}
p1->mc=count+1;
count=0;
}
return head;
}
struct StuLink* Edit_Node(struct StuLink* head)
{
struct StuLink *p=head;
int num;
printf("请输入要修改学生的学号:");
scanf("%d",&num);
while( p->xh != num && p->next!=NULL)
{
p=p->next;
}
if(p->xh==num)
{
int score;
char name[20];
printf("学号=%d,姓名=%s,成绩=%d,等级=%c,名次=%d\n",p->xh,p->xm,p->cj,p->dj,p->mc);
printf("请输入姓名和成绩:\n");
scanf("%s%d",name,&score);
while(!(score>=0 && score<=100) )
{
printf("输入成绩错误,请重新输入");
scanf("%s%d",name,&score);
}
strcpy(p->xm,name);
p->cj=score;
if(score>=90) p->dj='A';
else if(score>=80 && score<90) p->dj='B';
else if(score>=70 && score<80) p->dj='C';
else if(score>=60 && score<70) p->dj='D';
else p->dj='E';
head=Rank_Link(head);
printf("\n名次计算结果和链表修改结果如下:\n");
display_by_xh(head);
}
else printf("该学号学生不存在\n");
return head;
}
struct StuLink* Delete_Node(struct StuLink* head)
{
struct StuLink *p1,*p2;
int num;
printf("请输入删除的学生学号:");
scanf("%d",&num);
p1=head;
while( num != p1->xh && p1->next!=NULL)
{
p2=p1;
p1=p1->next;
}
if(p1->xh==num)
{
if(head==p1)head=p1->next;
else p2->next=p1->next;
printf("删除成功\n");
head=Rank_Link(head);
printf("\n名次计算结果和链表删除结果如下:\n");
display_by_xh(head);
}
else printf("找不到学号为%d的学生\n",num);
return head;
}
void Query_Node(struct StuLink* head)
{
struct StuLink *p1=head;
int num;
printf("请输入要查询的学生学号:");
scanf("%d",&num);
while( num != p1->xh && p1->next!=NULL)
{
p1=p1->next;
}
if(p1->xh == num)
{
printf("学号=%d, 姓名=%s, 成绩=%d, 等级=%c 名次=%d \n",p1->xh,p1->xm,p1->cj,p1->dj,p1->mc);
}
else printf("找不到学号为%d的学生\n",num);
}
void Analysis_Link(struct StuLink *head)
{
int a[5]={0},i;
struct StuLink *p1=head;
while(p1 != NULL)
{
if(p1->dj == 'A') a[0]++;
else if(p1->dj == 'B') a[1]++;
else if(p1->dj == 'C') a[2]++;
else if(p1->dj == 'D') a[3]++;
else if(p1->dj == 'E') a[4]++;
p1=p1->next;
}
printf("A:90分及以上 B:80分及以上 C:70分及以上 D:60分及以上 E:60分以下\n");
printf("A级人数=%d\n",a[0]);
printf("B级人数=%d\n",a[1]);
printf("C级人数=%d\n",a[2]);
printf("D级人数=%d\n",a[3]);
printf("E级人数=%d\n",a[4]);
}
void Output_Link(struct StuLink *head,int n)
{
if(n==1)display_by_xh(head);
else display_by_cj(head);
}
void Sort_Link(struct StuLink* head,int n)
{
if(n==2)display_by_xh(head);
else display_by_cj(head);
}
void display_by_xh(struct StuLink* head)
{
struct StuLink *p=NULL, *p1=NULL;
for(p=head;p!=NULL;p=p->next)
for(p1=p->next;p1!=NULL;p1=p1->next)
if(p->xh > p1->xh)swap(p,p1);
printf("学号\t\t姓名\t成绩\t等级\t名次\n");
for(p=head;p!=NULL;p=p->next)
printf("%d\t\t%s\t%d\t%c\t%d\n",p->xh,p->xm,p->cj,p->dj,p->mc);
}
void display_by_cj(struct StuLink* head)
{
struct StuLink* p=NULL,*p1=NULL;
for(p=head;p!=NULL;p=p->next)
for(p1=p->next;p1!=NULL;p1=p1->next)
if(p->cj < p1->cj)swap(p,p1);
printf("学号\t\t姓名\t成绩\t等级\t名次\n");
for(p=head;p!=NULL;p=p->next)
printf("%d\t\t%s\t%d\t%c\t%d\n",p->xh,p->xm,p->cj,p->dj,p->mc);
}
void swap(struct StuLink* p1, struct StuLink* p2)
{
int temp;
char c_temp;
char t_name[20];
c_temp=p1->dj,p1->dj=p2->dj,p2->dj=c_temp;
strcpy(t_name,p1->xm);
strcpy(p1->xm,p2->xm);
strcpy(p2->xm,t_name);
temp=p1->xh, p1->xh=p2->xh, p2->xh=temp;
temp=p1->cj, p1->cj=p2->cj, p2->cj=temp;
temp=p1->mc, p1->mc=p2->mc, p2->mc=temp;
}