双链表嵌套实现简单学生成绩管理系统

双链表嵌套实现简单学生成绩管理系统

(师承上官可编程)

场景:一个年级,相当于链表A,该年级5个班,每个班5个人,相当于链表B1–B5。功能:录入学生基本信息和成绩,找出最高分、最低分、平均分。

全代码展示

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct Class                   //班级结构体
{
 char *Class;
 struct Class *next;
 struct Student *Stuhead;
};

struct Student                 //学生结构体
{
 char *Name;
 int Chinese;
 int Math;
 int English;
 int Sum;
 struct Student *next;
};

struct Class *Chead = NULL;
struct Student *Shead = NULL;

void PrintClassStudent()            //输出所有学生的信息
{
 struct Class *p1;
 p1 = Chead;
 struct Student *p2 = NULL;
 while (p1 != NULL)
 {
  p2 = p1->Stuhead;          
  while (p2 != NULL)
  {
   printf("%s\n", p1->Class);
   printf("%s的%s\n", p1->Class, p2->Name);
   printf("%s的%s语文成绩为:%d\n", p1->Class, p2->Name, p2->Chinese);
   printf("%s的%s数学成绩为:%d\n", p1->Class, p2->Name, p2->Math);
   printf("%s的%s英语成绩为:%d\n", p1->Class, p2->Name, p2->English);
   printf("%s的%s三科总成绩为:%d\n", p1->Class, p2->Name, p2->Sum);
   p2 = p2->next;
  }
  p1 = p1->next;
 }
}


struct Student *AddStudentNode(struct Student *Shead, struct Student *new)
{
 struct Student *p;    //尾插法创建学生链表
 p = Shead;
 if (Shead == NULL)
 {
  Shead = new;
  return Shead;
 }
 while (p->next != NULL)
 {
  p = p->next;
 }
 p->next = new;
 return Shead;
}

struct Student *ScanfStudent(struct Student *Shead)    //输入学生信息
{
 struct Student *p;
 p = Shead;
 int i;
 for (i = 0; i < 5; i++)
 {
  struct Student *new = (struct Student *)malloc(sizeof(struct Student));
  new->Name = (char *)malloc(sizeof(char));
  new->next = NULL;
  printf("请输入学生姓名\n");
  scanf("%s", new->Name);
  printf("请输入学生语文成绩\n");
  scanf("%d", &(new->Chinese));
  printf("请输入学生数学成绩\n");
  scanf("%d", &(new->Math));
  printf("请输入学生英语成绩\n");
  scanf("%d", &(new->English));
  new->Sum = new->Chinese + new->Math + new->English;
  p = AddStudentNode(p, new);
 }
  return p;
}


struct Class *AddClassNode(struct Class *Chead, struct Class *new)//尾插法创建班级链表
{
 struct Class *p;
 p = Chead;
 if (Chead == NULL)
 {
  Chead = new;
  return Chead;
 }
 while (p->next != NULL)
 {
  p = p->next;
 }
 p->next = new;
 return Chead;
}

struct Class *ScanfClass(struct Class *Chead)    //输入班级信息
{
 struct Class *p;
 struct Class *new;
 p = Chead;
 new = (struct Class *)malloc(sizeof(struct Class));
 new->Class = (char *)malloc(sizeof(char));
 new->next = NULL;
 new->Stuhead = NULL;
 printf("请输入班级\n");
 scanf("%s", new->Class);
 new->Stuhead = ScanfStudent(Shead);
 p = AddClassNode(p,new);
 return p;
}

struct Class* AllNode()    //连接班级链表
{
 int i;
 for (i = 0; i < 5; i++)
 {
  Chead = ScanfClass(Chead);
 }
 return Chead;
}

int SumMax(struct Class *Chead)   //获取学生的最高分
{
 int mark = 0;
 struct Class *p1;
 p1 = Chead;
 struct Student *p2 = NULL;
 mark = p1->Stuhead->Sum;
 while (p1 != NULL)
 {
  p2 = p1->Stuhead;
  while (p2 != NULL)
  {
   if (p2->Sum > mark)
   {
    mark = p2->Sum;
   }
   p2 = p2->next;
  }
  p1 = p1->next;
 }
 return mark;
}

int SumMin(struct Class *Chead)  //获取学生的最低分
{
 int mark = 0;
 struct Class *p1;
 p1 = Chead;
 struct Student *p2 = NULL;
 mark = p1->Stuhead->Sum;
 while (p1 != NULL)
 {
  p2 = p1->Stuhead;
  while (p2 != NULL)
  {
   if (p2->Sum < mark)
   {
    mark = p2->Sum;
   }
   p2 = p2->next;
  }
  p1 = p1->next;
 }
 return mark;
}

float Average(struct Class *Chead) //获取学生的平均分
{
 float mark = 0;
 struct Class *p1;
 p1 = Chead;
 struct Student *p2 = NULL;
 while (p1 != NULL)
 {
  p2 = p1->Stuhead;
  while (p2 != NULL)
  {
   mark = mark + p2->Sum;
   p2 = p2->next;
  }
  p1 = p1->next;
 }
 return mark/25;
}

int main()
{
 Chead = AllNode();
 printf("-----------------------------\n");
 PrintClassStudent();
 printf("-----------------------------\n");
 printf("全年级最高分为:%d\n",SumMax(Chead));
 printf("-----------------------------\n");
 printf("全年级最低分为:%d\n",SumMin(Chead));
 printf("-----------------------------\n");
 printf("平均分为:%f\n",Average(Chead));

system("pause");
return 0;
}

要点(链表的动态创建)

个人见解:链表的创建有头插法和尾插法,我用的是尾插法创建学生和班级链表,核心:一开始输入数据时,头节点都为空,这就需要判断,如果头节点为空的话,让头节点等于新创建的节点即可,切记要return head;不然就会出现段错误。当插入第二个节点时,头节点不为空,就需要(使用while循环)找到最后一个节点,让p->next = new 即可。

注意:不能轻易改头节点,不然指针会跑飞。

总结

个人见解:这个系统是一个双链表系统,母链表的每一个节点包含一个子链表的头节点,可以根据这个思想来创建和遍历链表,核心就是建立好这个双链表,其他的可以根据遍历链表来找出最高分、最低分、平均分。如图:
在这里插入图片描述

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值