用单链表实现学生信息管理系统(大作业)

用单链表实现:

学生信息管理系统使用单链表作为基本数据结构,设计一个学生成绩管理系统,用来管理学生的成绩。

功能从0-9选择,根据提示输入相应序号对应实现不同的功能。

完整代码实现:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct student{	//学生信息 
    char sno[20];//学号 
	char name[20];//姓名 
	int chinese;//语文成绩 
	int math;//数学成绩 
	int english;//英语成绩 
	int score;//总分 
}stu;
typedef struct Lnode {//链表结点定义 
	stu data;	//数据域 
	struct Lnode *next;//指针域 
}LinkList;
//初始化链表 
LinkList *InitList(){
	LinkList *head;
	head=(LinkList *)malloc(sizeof(LinkList));//动态分配一个结点空间 
	head->next=NULL;
	return head;//头结点L指针为空,表示空链表 
}

int LengthList(LinkList *head){//链表长度 
	LinkList *p=head->next;
	int k=0;
	while(p!=NULL){
		p=p->next;
		k++;
	}
	return k;
}
void menu(){//菜单 
	printf("\n==================================");
	printf("\n\t1.--创建链表");
	printf("\n\t2.--显示链表");
	printf("\n\t3.--求每门课程的平均分");
	printf("\n\t4.--求成绩最大值");
	printf("\n\t5.--按学号查找学生");
	printf("\n\t6.--按序号位置查找学生");
	printf("\n\t7.--按序号删除学生");
	printf("\n\t8.--插入学生操作");
	printf("\n\t9.--对学生按分数进行排序");
	printf("\n\t0.--返回");
	printf("\n==================================");
	printf("\n==请输入==");
	printf("\n请输入选择项:\n");
}
//1.创建链表 
void CreateListL(LinkList *head,int n){//尾插法建表 
	LinkList *s,*last;
	int i;
	last=head;	//last始终指向尾结点,开始时指向头结点 
	for(i=0;i<n;i++){
		s=(LinkList *)malloc(sizeof(LinkList));//生成新节点 
		printf("请输入第%d个同学的学号,姓名,数学成绩,语文成绩,英语成绩:",i+1);//创建提示 
		scanf("%s%s%d%d%d",&s->data.sno,&s->data.name,&s->data.math,&s->data.chinese,&s->data.english);//读入新结点数据域 
		s->next=NULL;	//新结点指针域为空 
		last->next=s;	//新结点插入表尾 
		last=s;			//last指针指向表尾结点
	}
	printf("\n建立链表操作成功!\n");
}
//2.显示链表 
void DispList(LinkList *head){
	LinkList *p;
	p=head->next;
	printf("id\tname\tMath\tChinese\tEnglish\tscore\n");
	while(p!=NULL){
		p->data.score=p->data.math+p->data.chinese+p->data.english; //求各成绩总分score
		printf("%s\t%s\t%d\t%d\t%d\t%d\n",p->data.sno,p->data.name,p->data.math,p->data.chinese,p->data.english,p->data.score);//打印输出各项信息 
		p=p->next;
	}
}
//3.每门课程平均分 
void AveGrade(LinkList *head){
	LinkList *p;
	p=head->next;
	int y=LengthList(head);
	printf("共有%d个学生信息\n",y);//后面插入及删除学生,学生人数会变化,便于计算平均分 
	double aveMath,aveChinese,aveEnglish;//每门平均成绩 
	double SumEnglish,SumMath,SumChinese;//每门成绩之和 
	while(p!=NULL){
		SumMath+=p->data.math;		//各成绩求和 
		SumChinese+=p->data.chinese;
		SumEnglish+=p->data.english;
		p=p->next;
	}
	aveMath=SumMath/y;
	aveChinese=SumChinese/y;
	aveEnglish=SumEnglish/y;
	printf("各门课程的平均分如下:\n");
	printf("aveMath=%0.4f \t aveChinese=%0.4f \t aveEnglish=%0.4f",aveMath,aveChinese,aveEnglish);//打印输出平均分保留四位小数 
}
//4.求成绩最大值 
void MaxGrade(LinkList *head){
	LinkList *p;
	int i=1,k,MAX;
	p=head->next;
	while(p!=NULL){
		if(p->data.score>MAX){//找出最大score 
			MAX=p->data.score;
			k=i;//记录位置 
		}else{
			MAX=MAX;
		}
//		printf("%d  ",p->data.score);	//score 
		p=p->next;
		i++;
	}
	printf("\n成绩最大值的位置:%d,成绩为:%d \n",k,MAX);
}
//5.按学号查找学生 
void SnoLocate(LinkList *head, char *str){
	int flag=1;//记录位置 
	LinkList *p;
	p=head->next;
	while(p!=NULL){
		if(strcmp(p->data.sno,str)==0){	//字符串进行比较 相等找到学号并输出信息,没有找到返回主菜单 
		printf("在表的第%d个位置上找到该学生,学号:%s,姓名:%s\n",flag,p->data.sno,p->data.name);
		}
		p=p->next;
		flag++; 
	}
}
//6.按序号位置查找学生 
void SearchList(LinkList *head,int i){
	LinkList *p;
	int j=0;
	p=head;//p指向链表的头结点 
		if(i>LengthList(head))
			printf("位置错误,链表中没有找到该位置!\n");
	while(p->next!=NULL && j<i){
		p=p->next;
		j++;
	}
	if(j==i){	//判断与输入的序号位置是否相等 
		printf("在第%d位置上找到学生,学号为:%s 姓名为:%s",i,p->data.sno,p->data.name);
	}
}
//7.按序号删除操作 
void DelList(LinkList *head,int i){
	int j=0;
	stu x;
	LinkList *p=head,*s;
	while(p->next!=NULL && j<i-1){//定位插入点 
		p=p->next;
		j++;
	}
	if(p->next!=NULL && j==i-1){
		s=p->next;
		x=s->data;//将要删除的数据放入指针变量x中 
		p->next=s->next;//将p结点的指针域与q结点后面元素相连 
		free(s);
//		printf("删除学生后的链表内容如下:\n");
//		DispList(head);
	} else{
		printf("删除失败!\n");
	}
}
//8.插入学生操作 
void InsList(LinkList *head,int i,stu x){
	int j=0;
	LinkList *p,*s;
	p=head;
	while(p->next!=NULL && j<i-1){//定位插入位置,找到第i-1个结点 
		p=p->next;
		j++;
	}
	if(p!=NULL){
		s=(LinkList *)malloc(sizeof(LinkList));//申请新的结点空间s 
		s->data=x;//将数据x放入新结点的数据域中 
		s->next=p->next;//将新结点s的指针域与p结点后面元素相连 
		p->next=s;//将p与新结点s连接 
		printf("插入成功!\n");
	}
}
//9降序score排序
void find(stu *data,LinkList *head){	
	int i=1;	//用i来记录最高结点位置 
    LinkList *p = head;
    p = head->next;
    *data = p->data;
    while (p->next!=NULL) {
        p = p->next;
        if (p->data.score > data->score) {
            *data = p->data;
            i++;
        }
    }
//    data->score=data->math+data->chinese+data->english; //总分score				
//    printf("%s\t%s\t%d\t%d\t%d\t%d\n",data->sno,data->name,data->math,data->chinese,data->english,data->score);//打印输出score最大的那一行信息 
//    printf("位置:%d",i);	//最大分数的位置 
    DelList(head,i);//按最大score信息并从A表删除,调用删除函数 
}
void buildlistB(LinkList *B,LinkList *head,stu *data,int n){			//用尾插法创建链表B 
	LinkList *s,*last;
	last=B;
	for(int j=0;j<n;j++){
		s=(LinkList *)malloc(sizeof(LinkList));//生成新节点
		find(data,head); 	//调用  找出score最大函数
		s->data=*data;  //将最大score依次存入
		s->next=NULL;	//新结点指针域为空 
		last->next=s;	//新结点插入表尾 
		last=s;			//last指针指向表尾结点
	}
	printf("\n建立链表操作成功!\n");
}
int main(){
	int i,n;
	char str[20];
	stu x;
	stu L;
	LinkList *head,*p;
	char ch1,ch2,a;
	ch1='Y';
	while(ch1=='Y' || ch2=='y'){
		menu();
		scanf("%c",&ch2);
		getchar();
		switch(ch2){
			case '1':
				head=InitList();
				printf("初始化完成!\n");
				printf("请输入学生人数:\n");
				scanf("%d",&n);
				CreateListL(head,n);
				break;
			case '2':
				DispList(head);
				break;
			case '3':
				AveGrade(head);
				break;
			case '4':
				MaxGrade(head);
				break;
			case '5':
				printf("请输入查找的学号:");
				scanf("%s",&str);
				SnoLocate(head,str);
				break;
			case '6':
				printf("请输入要查找学生的位置:\n");
				scanf("%d",&i); 
				SearchList(head,i);
				break;
			case '7':
				printf("请输入要删除学生的位置:\n");
				scanf("%d",&i); 
				DelList(head,i);
				printf("删除成功!\n");
				break;
			case '8':
				label:
				printf("请输入要插入学生的位置:\n");
				scanf("%d",&i);
				getchar();
				if(i>LengthList(head)+1){
					printf("插入错误,请重新插入!\n");
					goto label;
				}
				printf("请输入要插入同学的 学号,姓名,数学成绩,语文成绩,英语成绩:");
				scanf("%s%s%d%d%d",&x.sno,&x.name,&x.math,&x.chinese,&x.english);
				InsList(head,i,x);
				break;
			case '9':
				LinkList *B;
				B=InitList();		//B表初始化 
				printf("初始化完成!\n");
				int m;
				m=LengthList(head);
				buildlistB(B,head,&L,m);		//链表B建立函数 
				printf("A链表为空:\n");
				DispList(head);			//显示链表A内容:为空 
				printf("\nB链表进行降序排序:\n");
				DispList(B);		//显示链表B内容(降序) 
				break;
			case '0':
				ch1='n';
				break;
			default:
				printf("输入有误!,请重新输入(0-9)!\n");
		}
		if(ch2!='0'){
			printf("\n按回车键继续,按任意键返回主菜单\n");
			a=getchar();
			if(a!='\xA'){
				getchar();ch1='n';
			}
		}
	}
}

示例运行截图:

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值