双链表嵌套的简单学生信息管理系统

参考:实现双链表嵌套的简单学生信息管理
作者:三速何时sub20
发布时间: 2020-07-20 10:44:40
网址:https://blog.csdn.net/weixin_44234294/article/details/107458155?spm=1001.2014.3001.5501

参考:双链表嵌套实现简单学生成绩管理系统
作者:0~∞
发布时间: 2021-06-14 22:43:56
网址:https://blog.csdn.net/m0_47561451/article/details/117913579?spm=1001.2014.3001.5501

题目

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

思路

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

参考代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//函数的声明(先定义的函数先使用了 可以不用声明)
struct Class *ClassMessage(struct Class *head,int Classnum,int stunum);
struct student *stuMessage(struct student *head,int stunum,int Classnum);
struct student *insertStuMessage(struct student *head,struct student *newData2);
void printMessage(struct Class *head,int stunum,int Classnum);
void findMathMaxScore(struct Class *head,int Classnum,int stunum);
void findChineseMaxScore(struct Class *head,int Classnum,int stunum);
void findEnglishMaxScore(struct Class *head,int Classnum,int stunum);
void gradeAvg(struct Class *head,int Classnum,int stunum);

//学生信息结构体
struct student
{
    int data;
    int chinese;
    int math;
    int english;
    int sum;
    float avg;
    struct student *next;
};
//班级结构体
struct Class
{
    int ClassNum;
    struct student *messageHead;//定义一个结构体指针指向学生信息链表
    struct Class *next;
};



//1、班级和学生链表(嵌套)创建
struct Class *ClassMessage(struct Class *head,int Classnum,int stunum)
{
   
    int j;
    struct Class *p=head;
    struct Class *newData=NULL;//用来新建信息的班级
    struct student *stuHead;   
    for(j=0;j<Classnum;j++){   //班级链表的创建
        newData=(struct Class *)malloc(sizeof(struct Class));
        newData->ClassNum = j+1;                                             //班级链表的内容
        stuHead=stuMessage(stuHead,stunum,j+1);//嵌套创建学生链表
        newData->messageHead=stuHead;                                        //班级链表的内容
       
        printf("#######################################\n");
         if(p == NULL){
            head = newData;
        }else{
            
                newData->next=head;//头插法                                  //班级链表的内容
                head=newData;
        }
    
    }
    return head;
}

//录入一个学生信息
struct student *stuMessage(struct student *head,int stunum,int Classnum)
{
    int i;
    int sum;
    float avg;
    struct student *newData;
    for(i=0;i<stunum;i++){
        newData=(struct student *)malloc(sizeof(struct student));
        printf("请输入%d班第%d位学生学号\n",Classnum,i+1);
        scanf("%d",&(newData->data));
        printf("chinese:\n");
        scanf("%d",&(newData->chinese));
        printf("math:\n");
        scanf("%d",&(newData->math));
        printf("english:\n");
        scanf("%d",&(newData->english));
        newData->sum=newData->chinese+newData->math+newData->english;
        newData->avg=(float)newData->sum/3;

        head=insertStuMessage(head,newData);//调用上面的头插法函数新建学生信息
    }
    return head;


}


//头插法插入到学生信息链表
struct student *insertStuMessage(struct student *head,struct student *newData2)
{
    if(head == NULL){
        head=newData2;
    }else{
        newData2->next=head;
        head=newData2;
    }
    return head;

}

//2、班级和学生链表的遍历打印
void printMessage(struct Class *head,int stunum,int Classnum)
{
    int i;
    int j;
    struct Class *p=head;//本来的链表头复制一份给P 用来自增遍历链表 这样就不会改变原有的链表形态
    struct student *p2=NULL;
    for(i=0;i<Classnum;i++){
       p2=p->messageHead;//让p2指向class结构体里面指向学生信息的指针
        for(j=0;j<stunum;j++){
            printf("第%d班第%d个学生:学号 %d\n",p->ClassNum,j+1,p2->data);
            printf("成绩:chinese:%d math:%d english:%d \n",p2->chinese,p2->math,p2->english);
            printf("总分:%d 平均分:%f\n",p2->sum,p2->avg);
            printf("---------------------------------\n");        
            p2=p2->next;
        }
        p=p->next;

    }
    

}


//3、链表遍历找数学最高分的学生
void findMathMaxScore(struct Class *head,int Classnum,int stunum)
{
    struct Class *pclass=head;
    struct student *pstu;
    int maxScore=0;
    int stuHao;
    int classHao;
    int i;
    int j;
    for(i=0;i<Classnum;i++){
        pstu=pclass->messageHead;
        for(j=0;j<stunum;j++){
            if(maxScore < pstu->math){
                maxScore=pstu->math;
                classHao=pclass->ClassNum;
                stuHao=pstu->data;
            }
            pstu=pstu->next;
        }
        pclass=pclass->next;

    }
    printf("-------------年级数学最高分--------------\n");
    printf("数学最高分是: %d班 学号 %d 分数 %d分\n",classHao,stuHao,maxScore);

}

//4、链表遍历找语文最高分的学生
void findChineseMaxScore(struct Class *head,int Classnum,int stunum)
{
    struct Class *pclass=head;
    struct student *pstu;
    int maxScore=0;
    int stuHao;
    int classHao;
    int i;
    int j;
    for(i=0;i<Classnum;i++){
        pstu=pclass->messageHead;
        for(j=0;j<stunum;j++){
            if(maxScore < pstu->chinese){
                maxScore=pstu->chinese;
                classHao=pclass->ClassNum;
                stuHao=pstu->data;
            }
            pstu=pstu->next;
        }
        pclass=pclass->next;

    }
    printf("---------------年级语文最高分--------------\n");
    printf("语文最高分是: %d班 学号 %d 分数 %d分\n",classHao,stuHao,maxScore);

}

//5、链表遍历找英语最高分的学生
void findEnglishMaxScore(struct Class *head,int Classnum,int stunum)
{
    struct Class *pclass=head;
    struct student *pstu;
    int maxScore=0;
    int stuHao;
    int classHao;
    int i;
    int j;
    for(i=0;i<Classnum;i++){
        pstu=pclass->messageHead;
        for(j=0;j<stunum;j++){
            if(maxScore < pstu->english){
                maxScore=pstu->english;
                classHao=pclass->ClassNum;
                stuHao=pstu->data;
            }
            pstu=pstu->next;
        }
        pclass=pclass->next;

    }
    printf("---------------年级英语最高分--------------\n");
    printf("英语最高分是: %d班 学号 %d 分数 %d分\n",classHao,stuHao,maxScore);

}

//6、链表遍历计算年级均分
void gradeAvg(struct Class *head,int Classnum,int stunum)
{
    struct Class *pclass=head;
    struct student *pstu;
    int gradeSum=0;
    int numOfStu;
    float gradeAvg;
    int i;
    int j;
    for(i=0;i<Classnum;i++){
        pstu=pclass->messageHead;
        for(j=0;j<stunum;j++){
            numOfStu++;
            gradeSum+=pstu->sum; 
            pstu=pstu->next;
        }
        pclass=pclass->next;

    }
    gradeAvg=(float)gradeSum/numOfStu;
    printf("---------------年级平均分--------------\n");
    printf("年级平均分是%f\n",gradeAvg);
}
int main()
{
    int a;
    int b;
    struct Class *head;            //其实也是个野指针
    printf("请输入班级数量:\n");
    scanf("%d",&a);
    printf("请输入班级人数量:\n");
    scanf("%d",&b);
    head=ClassMessage(head,a,b);   //1、班级、学生链表的创建
    printMessage(head,b,a);        //2、班级、学生链表的遍历打印
    findMathMaxScore(head,a,b);    //3、数学最高
    findChineseMaxScore(head,a,b); //4、语文最高
    findEnglishMaxScore(head,a,b); //5、英语最高
    gradeAvg(head,a,b);            //6、年级均分
   
    system("pause");
    return 0;
}

运行结果

仔细观察,链表遍历输出学生信息的时候,发现遍历的顺序是从2班学号为2的学生开始往后遍历的,这是因为我们使用的是头插法创建链表,最后插入到链表的最先被遍历。

请输入班级数量:
2
请输入班级人数量:
2
请输入1班第1位学生学号
1
chinese:
87
math:
90
english:
45
请输入1班第2位学生学号
2
chinese:
78
math:
54
english:
67
#######################################
请输入2班第1位学生学号
1
chinese:
56
math:
89
english:
54
请输入2班第2位学生学号
2
chinese:
76
math:
89
english:
56
#######################################
第2班第1个学生:学号 2
成绩:chinese:76 math:89 english:56
总分:221 平均分:73.666664
---------------------------------
第2班第2个学生:学号 1
成绩:chinese:56 math:89 english:54
总分:199 平均分:66.333336
---------------------------------
第1班第1个学生:学号 2
成绩:chinese:78 math:54 english:67
总分:199 平均分:66.333336
---------------------------------
第1班第2个学生:学号 1
成绩:chinese:87 math:90 english:45
总分:222 平均分:74.000000
---------------------------------
-------------年级数学最高分--------------
数学最高分是: 1班 学号 1 分数 90分
---------------年级语文最高分--------------
语文最高分是: 1班 学号 1 分数 87分
---------------年级英语最高分--------------
英语最高分是: 1班 学号 2 分数 67分
---------------年级平均分--------------
年级平均分是140.166672
请按任意键继续. . .

问题探索

在学生结构体体面添加 char *name,用来曾加学生的名字信息,可是遍历结果体的时候就出现段错误。
学生结构体的地方
在这里插入图片描述
录入的地方
在这里插入图片描述
遍历的地方
在这里插入图片描述

感谢大佬指点了一下,加了名字的代码如下

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//学生信息结构体
struct student
{
    int data;
    char name[10];
    int chinese;
    int math;
    int english;
    int sum;
    float avg;
    struct student *next;
};
//班级结构体
struct Class
{
    int ClassNum;
    struct student *messageHead;//定义一个结构体指针指向学生信息链表
    struct Class *next;
};
//打印各个学生的相关信息
void printMessage(struct Class *head,int stunum,int Classnum)
{
    int i;
    int j;
    int k=1;//用来计算第几个学生的
    struct Class *p=head;
    struct student *p2=NULL;
    for(i=0;i<Classnum;i++){
       p2=p->messageHead;//让p2指向class结构体里面指向学生信息的指针
        for(j=0;j<stunum;j++){
            printf("第%d班第%d个学生:学号 %d 姓名:%s\n",p->ClassNum,k,p2->data,p2->name);
            printf("成绩:chinese:%d math:%d english:%d \n",p2->chinese,p2->math,p2->english);
            printf("总分:%d 平均分:%f\n",p2->sum,p2->avg);
            printf("---------------------------------\n");
            k++;
            p2=p2->next;
        }
        k=1;
        p=p->next;

    }
    

}
//使用头插法插入新的学生信息
struct student *insertStuMessage(struct student *head,struct student *newData2)
{
    if(head == NULL){
        head=newData2;
    }else{
        newData2->next=head;
        head=newData2;
    }
    return head;

}
//录入学生的相关信息
struct student *stuMessage(struct student *head,int stunum,int Classnum)
{
    int i;
    int num=stunum;
    int sum;
    float avg;
    struct student *newData;
    for(i=0;i<stunum;i++){
        newData=(struct student *)malloc(sizeof(struct student));
        printf("请输入%d班第%d位学生学号\n",Classnum,num);
        scanf("%d",&(newData->data));
        printf("请输入姓名:\n");
        scanf("%s",newData->name);
        printf("chinese:\n");
        scanf("%d",&(newData->chinese));
        printf("math:\n");
        scanf("%d",&(newData->math));
        printf("english:\n");
        scanf("%d",&(newData->english));
        sum=newData->chinese+newData->math+newData->english;
        newData->sum=sum;
        avg=(float)sum/3;
        newData->avg=avg;
        num--;
        head=insertStuMessage(head,newData);//调用上面的头插法函数新建学生信息
    }
    return head;


}
//班级链表的操作
struct Class *ClassMessage(struct Class *head,int Classnum,int stunum)
{
   
    int j;
    int num=Classnum;
    struct Class *p=head;
    struct Class *newData=NULL;//用来新建信息的班级
    struct student *stuHead;
    for(j=0;j<Classnum;j++){
        newData=(struct Class *)malloc(sizeof(struct Class));
        newData->ClassNum=num;
        stuHead=stuMessage(stuHead,stunum,num);
        newData->messageHead=stuHead;
       
        printf("#######################################\n");
        num--;
         if(p == NULL){
            head = newData;
        }else{
            
                newData->next=head;
                head=newData;
        }
        //newData=newData->next;
    
    }
    return head;
}
//找数学最高分的学生
void findMathMaxScore(struct Class *head,int Classnum,int stunum)
{
    struct Class *pclass=head;
    struct student *pstu;
    int maxScore=0;
    int stuHao;
    int classHao;
    int i;
    int j;
    char *name;
    name = (char *)malloc(10);
    for(i=0;i<Classnum;i++){
        pstu=pclass->messageHead;
        for(j=0;j<stunum;j++){
            memset(name,0,10);
            if(maxScore < pstu->math){
                maxScore=pstu->math;
                classHao=Classnum;
                stuHao=pstu->data;
                name=pstu->name;
            }
            pstu=pstu->next;
        }
        pclass=pclass->next;

    }
    printf("-------------年级数学最高分--------------\n");
    printf("数学最高分是: %d班 学号 %d 姓名 %s 分数 %d分\n",classHao,stuHao,name,maxScore);

}

void findChineseMaxScore(struct Class *head,int Classnum,int stunum)
{
    struct Class *pclass=head;
    struct student *pstu;
    int maxScore=0;
    int stuHao;
    int classHao;
    int i;
    int j;
    char *name;
    name = (char *)malloc(10);
    for(i=0;i<Classnum;i++){
        pstu=pclass->messageHead;
        for(j=0;j<stunum;j++){
            memset(name,0,10);
            if(maxScore < pstu->chinese){
                maxScore=pstu->chinese;
                classHao=pclass->ClassNum;
                stuHao=pstu->data;
                name=pstu->name;
            }
            pstu=pstu->next;
        }
        pclass=pclass->next;

    }
    printf("---------------年级语文最高分--------------\n");
    printf("语文最高分是: %d班 学号 %d 姓名 %s 分数 %d分\n",classHao,stuHao,name,maxScore);

}
void findEnglishMaxScore(struct Class *head,int Classnum,int stunum)
{
    struct Class *pclass=head;
    struct student *pstu;
    int maxScore=0;
    int stuHao;
    int classHao;
    int i;
    int j;
    char *name;
    name = (char *)malloc(10);
    for(i=0;i<Classnum;i++){
        pstu=pclass->messageHead;
        for(j=0;j<stunum;j++){
            memset(name,0,10);
            if(maxScore < pstu->english){
                maxScore=pstu->english;
                classHao=pclass->ClassNum;
                stuHao=pstu->data;
                name=pstu->name;
                
            }
            pstu=pstu->next;
        }
        pclass=pclass->next;

    }
    printf("---------------年级英语最高分--------------\n");
    printf("英语最高分是: %d班 学号 %d 姓名 %s 分数 %d分\n",classHao,stuHao,name,maxScore);

}
void gradeAvg(struct Class *head,int Classnum,int stunum)
{
    struct Class *pclass=head;
    struct student *pstu;
    int gradeSum=0;
    int numOfStu;
    float gradeAvg;
   // float maxAvg;
    int i;
    int j;
    for(i=0;i<Classnum;i++){
        pstu=pclass->messageHead;
        for(j=0;j<stunum;j++){
            numOfStu++;
            gradeSum+=pstu->sum; 
            pstu=pstu->next;
        }
        pclass=pclass->next;

    }
    gradeAvg=(float)gradeSum/numOfStu;
    printf("---------------年级平均分--------------\n");
    printf("年级平均分是%f\n",gradeAvg);
}
int main()
{
    int a;
    int b;
    struct Class *head;
    printf("请输入班级数量:\n");
    scanf("%d",&a);
    printf("请输入班级人数量:\n");
    scanf("%d",&b);
    head=ClassMessage(head,a,b); 
    printMessage(head,b,a);
    findMathMaxScore(head,a,b);
    findChineseMaxScore(head,a,b);
    findEnglishMaxScore(head,a,b);
    gradeAvg(head,a,b);
    return 0;
}
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行稳方能走远

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值