题目
基于链式存储的学生成绩管理系统的设计 急!!! 15C
1,建立一张学生成绩表,每个学生包含“学号、姓名、性别、语文、数学、英语、平均分”
2,将该表中所有信息按平均分降序排列
3,按学号查找某学生所有成绩
4,插入某学生成绩在合适位置,不影响原来排序
(用链表实现)
前言
上面是问答的原题,默默表示现在都没有接到他的回复,可怜俺的代码啊!所有这篇博文出现了<_<
问题分析
首先一看到这个:学生包含“学号、姓名、性别、语文、数学、英语、平均分”就应该想到结构体(c语言里面),这是结构体存在的意义之一,就是存储不同数据类型的一个集合,这是数组解决不了的事情。然后是存储信息,就是链表的基本操作,增,删,查,改,当然还有销毁咯(基本操作不知道的可以查一下,很多,我也就不加追述了)。不过这里好像没有这么多要求,看上去好像感觉到,只是没有基本操作那么单纯而已。
为了规范化和模块化,个人还是建议写一个头文件和一个.c文件,用于主程序的调用。让主程序显得更加简洁。
按照他的要求1,建立一张学生成绩表,每个学生包含“学号、姓名、性别、语文、数学、英语、平均分”,这也就确定了结构体的成员,学号可以是unsigned int,语文、数学、英语、平均分这些可以是float(老师心情不好扣你10分<_<),也可以是unsigned float之类的。姓名,性别肯定是字符串咯。至于平均分没必要算,你可以写一个函数,自动算出,然后存进去,这样就简单方便。
至于第二点要求,将该表中所有信息按平均分降序排列就更简单了,因为增加一个结点就是一个数的插入,你可以刚开始就排好,类似于选择排序,输入一个就给你插在相应的位置,这样就不需要后期重新排序。
至于3,按学号查找某学生所有成绩,写一个学号匹配函数(也就是基本操作查)就可以了,4,插入某学生成绩在合适位置,不影响原来排序,当第二点满足时这点就满足了。
代码块
1.LIST.h头文件
#ifndef __LIST_H__
#define __LIST_H__
struct node
{
unsigned int student_num;//存储学号
char name[20];//姓名
char gender[6];//性别:man或者woman
float chinese;
float math;
float english;
float average;//存储平均成绩
struct node * next;
};
typedef struct node Node;//结点的别名
struct hnode
{
Node * first;//第一个结点的地址
unsigned class_num;//这个班级(表)的人数
};
typedef struct hnode Hnode;//头结点的类型
/*
Hnode * create_list();
创建一个空链表,返回链表的头结点
*/
Hnode * create_list();
/*
Hnode * increase_element(Hnode *h,Node *element);
增加一个学生的信息
@h:表的头结点,表示哪一个表
@element:增加的学生的信息
返回其头结点
*/
Hnode * increase_element(Hnode *h,Node *element);
/*
void average_score(Node *element);
求@element学生的平均成绩,并且存入其@element信息中
@element:表示学生的信息
*/
void average_score(Node *element);
/*
void destory_list(Hnode *h);
销毁一张表或者一个班级的学生信息
@h:表的头结点或者表示某一个班级的头结点
*/
void destory_list(Hnode *h);
/*
void traverse_list(Hnode*h);
打印@h这张表的信息
*/
void traverse_list(Hnode*h);
/*
Node * search_list(Hnode *h,unsigned int num);
查找@num学号的学生信息
返回其学生的信息结构体地址
*/
Node * search_list(Hnode *h,unsigned int num);
#endif
2.LIST.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"list.h"
Hnode * create_list()
{
Hnode * h=(Hnode *)malloc(sizeof(Hnode));
h->class_num=0;
h->first=NULL;
return h;
}
Hnode * increase_element(Hnode *h,Node *element)
{
if(NULL==element)//增加的成员信息为空,则取消增加
{
return h;
}
Node *p=(Node *)malloc(sizeof(Node));
Node *q=NULL;
Node *before=NULL;
int i=0;
p->average=element->average;
p->chinese=element->chinese;
p->english=element->english;
p->math=element->math;
p->next=NULL;
p->student_num=element->student_num;
strcpy(p->gender,element->gender);//注意字符串不支持直接赋值
strcpy(p->name,element->name);//注意字符串不支持直接赋值
printf("succeed\n");//表示信息添加成功进入
//现在部分编译器直接struct直接整体赋值
if(NULL==h->first)//如果是增加第一个学生
{
h->first=p;
h->class_num++;//班级人数加一
return h;//返回头结点
}
else
{
q=h->first;
while(q)//查找第一个比新增成员平均成绩低的
{
if(p->average<q->average)//没有找到
{
before=q;//保存找到的前一个的地址
q=q->next;//继续下一个
i++;//记录比新增成员大的成员个数
}
else
{
break;//找到,跳出循环
}
}
if(0==i)//当新增成员信息比所有人的平均成绩高时
{
h->first=p;//插入最前面
p->next=q;//连接原来的信息
h->class_num++;
return h;
}
else//不是最前的时候的连接
{
before->next=p;
p->next=q;
h->class_num++;
return h;
}
}
return h;
}
void average_score(Node *element)
{
element->average=(element->chinese+element->english+element->math)/3;
}
Node * search_list(Hnode *h,unsigned int num)
{
if(NULL==h->first)//空表无法查询
{
return NULL;
}
Node *end=h->first;
while(end)//从头开始查找
{
if(num!=end->student_num)
{
end=end->next;
}
else
{
break;
}
}
return end;
}
void destory_list(Hnode *h)
{
if(NULL==h->first)//空表销毁
{
free(h);
return;
}
Node *p=h->first;
while(p)//销毁结点
{
p=h->first->next;
free(h->first);
h->first=p;
}
free(h);//销毁头结点
}
void traverse_list(Hnode*h)
{
Node *p=h->first;
while(p)
{
printf("%u %s %s %f %f %f %f\n",p->student_num,p->name,p->gender,p->chinese,p->math,p->english,p->average);
p=p->next;
}
}
主函数main.c
主函数仅仅只是本人用于测试写的,可以根据自己需求调用相应子程序进行修改,或者完善
#include<stdio.h>
#include"list.h"
int main()
{
Hnode *h=create_list();
Node student;
Node* search=NULL;
int k=0;
printf("请分别输入学生的学号 姓名 性别 语文成绩 数学成绩 英语成绩\n");
scanf("%d%s%s%f%f%f",&student.student_num,student.name,student.gender,&student.chinese,&student.math,&student.english);
average_score(&student);
h=increase_element(h,&student);
while(1)
{
printf("请问是否输入完成,完成为1,继续为0\n");
scanf("%d",&k);
if(1==k)
{
break;
}
scanf("%u%s%s%f%f%f",&student.student_num,student.name,student.gender,&student.chinese,&student.math,&student.english);
average_score(&student);
h=increase_element(h,&student);
}
printf("这是输入信息\n");
traverse_list(h);
while(1)
{
printf("请问是否需要查找,不需要为-1,需要请输入学号\n");
scanf("%d",&k);
if(-1==k)
{
break;
}
search=search_list(h,k);
if(NULL==search)
{
printf("没有这个学生\n");
break;
}
printf("查找的学生的学号是:%u\n",search->student_num);
printf("查找的学生为:%s\n",search->name);
printf("性别为:%s\n",search->gender);
printf("语文成绩为:%f 数学成绩为:%f 英语成绩为:%f\n",search->chinese,search->math,search->english);
printf("平均成绩是:%f\n",search->average);
}
destory_list(h);
return 0;
}
结果
运行环境:gcc
编辑环境:sources insight
结语
代码尽量写了注释(当然一些简单的地方也就忽略了),如果有什么疑问或者其他,欢迎私信或者留言,如果对你有什么帮助,可以点一个赞,谢谢!