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

结构体定义:

typedef struct Student
{
	char name[20];
	int id;
	float score;
}datatype;

typedef struct Node
{
	union
	{
		datatype data; 	//数据域
		int len;
	};
	struct Node *next; 	//指针域
}Linklist;

功能函数:

1.申请结点

//定义申请节点函数
Linklist * node_apply(datatype e)
{
	Linklist *p = (Linklist*)malloc(sizeof(Linklist));
	if(NULL == p)
	{
		printf("节点申请失败\n");
		return NULL;
	}
	//将数据存到节点中
	p->data = e;
	p->next = NULL;
	return p;
}

2.创建链表

//创建链表
Linklist *list_create()
{
	Linklist* L = (Linklist*)malloc(sizeof(Linklist));
	if(NULL == L)
	{
		printf("创建失败\n");
		return NULL;
	}

	//初始化
	L->len = 0;
	L->next = NULL;

	//printf("创建成功\n");
	return L;
}

3.链表判空

//判空
int list_empty(Linklist *L)
{
	//1表示空 	0表示非空
	return NULL==L->next ? 1:0;
}

4.遍历学生信息

//遍历学生信息
void stu_show(Linklist *L)
{
	//判断逻辑
	if(NULL==L || list_empty(L))
	{
		printf("无法遍历\n");
		return;
	}
	//遍历逻辑
	printf("学生信息如下:\n");
	printf("\n");
	//定义遍历指针遍历链表
	Linklist *q = L->next;
	while(q!=NULL)
	{
		printf("学生姓名:%s\t",q->data.name);
		printf("学生学号:%d\t",q->data.id);
		printf("学生成绩:%.2f\n",q->data.score);
		printf("\n");
		q = q->next;
	}
	printf("\n");
	return;
}

5.尾插法添加学生信息

//尾插法添加学生信息
int stu_insert_tail(Linklist *L,datatype e)
{
	//判断逻辑
	if(NULL == L)
	{
		printf("所给链表不合法\n");
		return -1;
	}
	//申请节点
	Linklist *p = node_apply(e);
	//遍历指针指向最后一个节点
	Linklist *q = L;
	while(q->next!=NULL)
	{
		q = q->next;
	}
	//尾插逻辑
	q->next = p;
	//表的变化
	L->len++;

	//printf("尾插成功\n");
	return 0;
}

6.根据姓名查找学生信息

//根据姓名查找学生信息
int stu_search_name(Linklist *L,char sname[20])
{
	//判断逻辑
	if(NULL==L || list_empty(L))
	{
		printf("查找失败\n");
		return -1;
	}

	//定义遍历指针遍历链表
	Linklist *q = L->next;
	while(q != NULL)
	{
		if(!strcasecmp(sname,q->data.name)) //判断字符串是否相等只能用string函数族中的函数
		{
			printf("查找到如下信息\n");
			printf("学生姓名:%s\t",q->data.name);
			printf("学生学号:%d\t",q->data.id);
			printf("学生成绩:%.2f\n",q->data.score);
			return 0; 			//查找到直接退出函数体
		}
		q = q->next;
	}
	printf("未找到相关信息\n");
	return 1;
}

7.根据学号查找学生信息

//根据学号查找学生信息
int stu_search_id(Linklist *L,int sid)
{
	//判断逻辑
	if(NULL==L || list_empty(L))
	{
		printf("查找失败\n");
		return -1;
	}

	//定义遍历指针遍历链表
	Linklist *q = L->next;
	while(q != NULL)
	{
		if(q->data.id == sid)
		{
			printf("查找到如下信息:\n");
			printf("学生姓名:%s\t",q->data.name);
			printf("学生学号:%d\t",q->data.id);
			printf("学生成绩:%.2f\n",q->data.score);
			return 0; 			//查找到直接退出函数体
		}
		q = q->next;
	}
	printf("未找到相关信息\n");
	return 1;
}

8.根据姓名删除学生信息

//根据姓名删除学生信息
int stu_delete_name(Linklist *L,char dname[20])
{
	//判断逻辑
	if(NULL==L || list_empty(L))
	{
		printf("删除失败\n");
		return -1;
	}

	//定义遍历指针遍历链表
	Linklist *q = L;
	while(NULL!=q->next && strcasecmp(dname,q->next->data.name)) 
	{
		q = q->next;
	}
	if(NULL != q->next)
	{
		Linklist *p = q->next; 		//标记
		q->next = p->next; 			//孤立
		free(p); 					//踢开
		p = NULL;

		//表的变化
		L->len--;
		printf("删除成功\n");
	}
	else
	{
		printf("未找到相关信息\n");
	}

	return 0;
}

9.根据学号删除学生信息

//根据学号删除学生信息
int stu_delete_id(Linklist *L,int did)
{
	//判断逻辑
	if(NULL==L || list_empty(L))
	{
		printf("删除失败\n");
		return -1;
	}

	//定义遍历指针遍历链表
	Linklist *q = L;
	while(NULL!=q->next && q->next->data.id!=did)
	{
		q = q->next;
	}
	if(NULL != q->next)
	{
		Linklist *p = q->next;
		q->next = p->next;
		free(p);
		p = NULL;

		L->len--;
		printf("删除成功\n");
	}
	else
	{
		printf("未找到相关信息\n");
	}

	return 0;
}

10.根据学生姓名修改学生信息

//根据学生姓名修改学生信息
int stu_update_name(Linklist *L,char uname[20],datatype e)
{
	//判断逻辑
	if(NULL==L || list_empty(L))
	{
		printf("修改失败\n");
		return -1;
	}
	//修改逻辑
	Linklist *p = L->next; 		//定义遍历指针
	while(p!=NULL) 		//遍历链表
	{
		if(!strcasecmp(p->data.name,uname)) //判断字符串是否相等
		{
			p->data = e;
			break;
		}
		p = p->next;
	}
	printf("学生信息修改成功\n");
	return 0;
}

11.根据学生学号修改学生信息

//根据学生学号修改学生信息
int stu_update_id(Linklist *L,int uid,datatype e)
{
	//判断逻辑
	if(NULL==L || list_empty(L))
	{
		printf("修改失败\n");
		return -1;
	}
	//修改逻辑
	Linklist *p = L->next; 		//定义遍历指针
	while(p!=NULL) 		//遍历链表
	{
		if(p->data.id == uid)
		{
			p->data = e;
			break;
		}
		p = p->next;
	}
	printf("学生信息修改成功\n");
	return 0;
}

12.按学号将学生排序

//按学号将学生排序
void stu_sort_id(Linklist *L,int flag)
{
	//判断逻辑
	if(NULL==L || list_empty(L))
	{
		printf("排序失败\n");
	}
	//冒泡排序
	Linklist *q = L->next; 		//定义遍历指针
	if(flag) 		//升序
	{
		for(int i=0;i<L->len-1;i++)
		{
			q = L->next; 		//每一轮排序开始前都要将遍历指针指回第一个结点
			for(int j=0;j<L->len-i-1;j++)
			{
				if(q->data.id>q->next->data.id) 	//大升小降
				{
					datatype temp = q->data; 		//三杯水交换
					q->data = q->next->data;
					q->next->data = temp;
				}
				q = q->next;
			}
		}
	}
	else 			//降序
	{
		for(int i=0;i<L->len-1;i++)
		{
			q = L->next;
			for(int j=0;j<L->len-i-1;j++)
			{
				if(q->data.id<q->next->data.id)
				{
					datatype temp = q->data;
					q->data = q->next->data;
					q->next->data = temp;
				}
				q = q->next;
			}
		}
	}
	//printf("排序成功\n");
}

13.按成绩将学生排序

//按成绩将学生排序
void stu_sort_score(Linklist *L,int flag)
{
	//判断逻辑
	if(NULL==L || list_empty(L))
	{
		printf("排序失败\n");
	}
	//冒泡排序
	Linklist *q = L->next; 		//定义遍历指针
	if(flag) 		//升序
	{
		for(int i=0;i<L->len-1;i++)
		{
			q = L->next;
			for(int j=0;j<L->len-i-1;j++)
			{
				if(q->data.score>q->next->data.score)
				{
					datatype temp = q->data;
					q->data = q->next->data;
					q->next->data = temp;
				}
				q = q->next;
			}
		}
	}
	else 			//降序
	{
		for(int i=0;i<L->len-1;i++)
		{
			q = L->next;
			for(int j=0;j<L->len-i-1;j++)
			{
				if(q->data.score<q->next->data.score)
				{
					datatype temp = q->data;
					q->data = q->next->data;
					q->next->data = temp;
				}
				q = q->next;
			}
		}
	}
	//printf("排序成功\n");
}

主函数:

int main(int argc, const char *argv[])
{
	//新建一个存放学生信息的单链表
	Linklist *L = list_create();

	//初始化几个变量并存入单链表中
	datatype e1;
	strcpy(e1.name,"zy");
	e1.id = 924;
	e1.score = 96;
	stu_insert_tail(L,e1);

	datatype e2;
	strcpy(e2.name,"yl");
	e2.id = 128;
	e2.score = 95;
	stu_insert_tail(L,e2);

	datatype e3;
	strcpy(e3.name,"wjm");
	e3.id = 562;
	e3.score = 100;
	stu_insert_tail(L,e3);

	datatype e4;
	strcpy(e4.name,"sy");
	e4.id = 357;
	e4.score = 91;
	stu_insert_tail(L,e4);

	while(1) 		//循环打印系统菜单
	{
		printf("--------------------------------\n");
		printf("------欢迎进入学生管理系统------\n");
		printf("---------1.添加学生信息---------\n");
		printf("---------2.查找学生信息---------\n");
		printf("---------3.删除学生信息---------\n");
		printf("---------4.修改学生信息---------\n");
		printf("-------5.显示全部学生信息-------\n");
		printf("-------6.退出学生管理系统-------\n");
		printf("--------------------------------\n");
		printf("请填写数字以选择相应功能:\n");

		int select;
		scanf("%d",&select);
		getchar(); 			//吸收垃圾字符防止陷入死循环
		switch(select)
		{
		case 1:
			{
				//初始化数据
				datatype e;

				//终端输入学生信息
				printf("请输入学生姓名:\n");
				scanf("%s",e.name);
				printf("请输入学生学号:\n");
				scanf("%d",&e.id);
				printf("请输入学生成绩:\n");
				scanf("%f",&e.score);

				//尾插法添加学生信息
				stu_insert_tail(L,e);

				printf("添加成功\n");
				break;
			}
		case 2:
			{
				//提示查找方式
				printf("请选择按什么查找:\n");
				printf("1.姓名\t2.学号\n");
				int select1;
				scanf("%d",&select1);
				switch(select1)
				{
				case 1:
					{
						//终端输入想要查找的学生姓名
						char sname[20];
						printf("请输入要查找的学生姓名:\n");
						scanf("%s",sname);
						//根据姓名查找学生信息
						stu_search_name(L,sname);
						break;
					}
				case 2:
					{
						int sid;
						printf("请输入要查找的学生学号:\n");
						scanf("%d",&sid);
						//根据学号查找学生信息
						stu_search_id(L,sid);
						break;
					}
				default:
					{
						printf("你输入的数字有误!\n");
						break;
					}

				}
				break;
			}
		case 3:
			{
				//提示删除方式
				printf("请选择按什么删除:\n");
				printf("1.姓名\t2.学号\n");
				int select2;
				scanf("%d",&select2);
				switch(select2)
				{
				case 1:
					{
						char dname[20];
						printf("请输入要删除的学生姓名:\n");
						scanf("%s",dname);
						int res = stu_search_name(L,dname);
						if(!res)
						{
							char answer;
							getchar(); 		//吸收空格
							printf("你确定要删除吗?(回复y或n)\n");
							scanf("%c",&answer);
							if(answer=='y' || answer=='Y')
							{
								//根据姓名删除学生信息
								stu_delete_name(L,dname);
								break;
							}
							else if(answer=='n' || answer=='N')
							{
								printf("已取消删除\n");
								break;
							}
							else
							{
								printf("你输入的回复有误!\n");
								break;
							}
						}
						break;
					}
				case 2:
					{
						int did;
						printf("请输入要删除的学生学号:\n");
						scanf("%d",&did);
						int res = stu_search_id(L,did);
						if(!res)
						{
							char answer;
							getchar();
							printf("你确定要删除吗?(回复y或n)\n");
							scanf("%c",&answer);
							if(answer=='y' || answer=='Y')
							{
								//根据学号删除学生信息
								stu_delete_id(L,did);
								break;
							}
							else if(answer=='n' || answer=='N')
							{
								printf("已取消删除\n");
								break;
							}
							else
							{
								printf("你输入的回复有误!\n");
								break;
							}
						}
						break;
					}
				default:
					{
						printf("你输入的数字有误!\n");
						break;
					}
				}
				break;
			}
		case 4:
			{
				//提示修改方式
				printf("请选择按什么查找要修改的学生信息:\n");
				printf("1.姓名\t2.学号\n");
				int select3;
				scanf("%d",&select3);
				switch(select3)
				{
				case 1:
					{
						char uname[20];
						printf("请输入要修改信息的学生姓名:\n");
						scanf("%s",uname);
						//先判断是否存在终端输入的学生姓名
						int res = stu_search_name(L,uname);
						if(!res)
						{
							datatype e_name;

							printf("请输入新的学生姓名:\n");
							scanf("%s",e_name.name);
							printf("请输入新的学生学号:\n");
							scanf("%d",&e_name.id);
							printf("请输入新的学生成绩:\n");
							scanf("%f",&e_name.score);
							//根据学生姓名修改学生信息
							stu_update_name(L,uname,e_name);
						}
						break;
					}
				case 2:
					{
						int uid;
						printf("请输入要修改信息的学生学号:\n");
						scanf("%d",&uid);
						//判断是否存在终端输入的学生学号
						int res = stu_search_id(L,uid);
						if(!res)
						{
							datatype e_id;

							printf("请输入新的学生姓名:\n");
							scanf("%s",e_id.name);
							printf("请输入新的学生学号:\n");
							scanf("%d",&e_id.id);
							printf("请输入新的学生成绩:\n");
							scanf("%f",&e_id.score);
							//根据学生学号修改学生信息
							stu_update_id(L,uid,e_id);

						}
						break;
					}
				default:
					{
						printf("你输入的数字有误!\n");
						break;
					}
				}
				break;
			}
		case 5:
			{
				//提示显示方式
				printf("请选择学生排序方式:\n");
				printf("1.学号升序\n");
				printf("2.学号降序\n");
				printf("3.成绩升序\n");
				printf("4.成绩降序\n");
				int select4;
				scanf("%d",&select4);
				switch(select4)
				{
				case 1:
					{
						stu_sort_id(L,1);
						stu_show(L);
						break;
					}
				case 2:
					{
						stu_sort_id(L,0);
						stu_show(L);
						break;
					}
				case 3:
					{
						stu_sort_score(L,1);
						stu_show(L);
						break;
					}
				case 4:
					{
						stu_sort_score(L,0);
						stu_show(L);
						break;
					}
				default:
					{
						printf("你输入的数字有误!\n");
					}
				}

				break;
			}
		case 6:
			{
				printf("退出成功\n");
				exit(0); 			//跳出死循环
			}
		default:
			{
				printf("你输入的数字有误!\n");
			}
		}
	}
	return 0;
}

测试结果:

1.测试添加学生信息功能及查找学生信息功能:

查找刚刚添加的学生hqy的信息发现能够被查找到,通过姓名和学号皆可。

 2.测试删除学生信息功能:

1)按姓名删除

 删除学生hqy后再查找hqy无结果

 2)按学号删除

 学生zy的信息也被删除

 3.测试修改学生信息功能:

1)按姓名修改

 遍历学生列表可见已修改成功

 2)按学号修改

 4.测试学生排序功能:

1)按学号排序

升序:

降序: 

 2)按成绩排序

升序:

降序:

 5.退出系统

 

  • 23
    点赞
  • 173
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值