2022/7/23——单向链表的学生信息管理系统

要求使用单向链表完成学生信息管理系统,完成其增删改查的功能

0)链表所使用的结构体

//存放学生的信息
typedef struct
{
	float score;     //分数
	char name[20];   //姓名
	int id;          //学号
}datatype;
//构成链表的结构体
typedef struct Node
{
	union{
		datatype data;   //数据域
		int len;   //链表长度
	};
	struct Node* next;   //指针域
}Student;

1)主函数使用菜单框架实现交互,并使用switch语句的嵌套实现功能条件的细化

功能的实现都依靠调用已封装的功能函数

#include<stdio.h>
#include<stdlib.h>
#include"./student.h"
#include<string.h>
int main(int argc, const char *argv[])
{
	int num;     //控制功能的变量
	Student *S=create();   //新建链表的头节点
	if(NULL==S)
	{
		return -1;
	}
    //菜单框架
	while(1)
	{
		printf("--------------------------------------------\n");
		printf("-------欢迎使用学生信息管理系统-------------\n");
		printf("1、增入学生信息\n");
		printf("2、输出所有的学生信息\n");
		printf("3、删除学生信息\n");
		printf("4、查找学生信息\n");
		printf("5、修改学生信息\n");
		printf("0、退出程序\n");
		printf("请输入想要实现的功能编号:");
		scanf("%d",&num);
		switch(num)
		{
		case 1:       //增
			{
				printf("开始输入信息(姓名处输入#表示信息输入完成)\n");
				while(1)
				{
					//外部输入数据并尾插入表中
					datatype val;
					printf("请输入姓名>>");
					scanf("%s",val.name);
					if(strcmp(val.name,"#")==0)    //判断信息是否输入完成
					{
						printf("信息输入完成\n");
						break;
					}
					printf("请输入学号>>");
					scanf("%d",&val.id);
					printf("请输入分数>>");
					scanf("%f",&val.score);
					list_intsrt_tail(S,val);
				}
			} break;
		case 2: list_show(S);  break;       //遍历链表元素
		case 3: 
			{
				int b;    //存放要实现功能编号
				printf("1、按学号删除\n");
				printf("2、按姓名删除\n");
				printf("3、按位置删除\n");
				printf("请输入想要实现的功能编号>>");
				scanf("%d",&b);
                //使用switch语句实现对删除条件的变化
				switch(b)
				{
				case 1:    //以学号为条件来删除特定信息
					{
						int del_id;
						printf("请输入想要删除的学号>>");
						scanf("%d",&del_id);
						list_delete_id(S,del_id); 
					}break;
				case 2:   //以姓名为条件来特定删除特定信息
					{
						char del_name[20];
						printf("请输入想要删除的姓名>>");
						scanf("%s",del_name);
						list_delete_name(S,del_name);
					}break;
				case 3:    //以位置为条件来删除特定信息
					{
						int pos;
						printf("请输入想要删除的位置>>");
						scanf("%d",&pos);
						list_delete_pos(S,pos);
					}
				default : printf("输入的编号有误\n"); break;
				}
			}break;
		case 4: 
			 {
				 int a;    //存放要实现功能编号
				 printf("1、按学号查找\n");
				 printf("2、按分数查找\n");
				 printf("3、按姓名查找\n");
				 printf("请输入想要实现的功能编号>>");
				 scanf("%d",&a);
                 //使用switch语句实现对查找条件的变化
				 switch(a)
				 {
				 case 1:      //以学号为条件来特定查找特定信息
					 {
						 int find_id;
						 printf("请输入学号>>");
						 scanf("%d",&find_id);
						 list_search_value_id(S,find_id);
					 }break;
				 case 2:     //以分数为条件来特定查找特定信息
					 {
						 float find_score;
						 printf("请输入分数>>");
						 scanf("%f",&find_score);
						 list_search_value_score(S,find_score);
					 }break;
				 case 3:     //以姓名为条件来特定查找特定信息
					 {
						 char find_name[20];
						 printf("请输入姓名>>");
						 scanf("%s",find_name);
						 list_search_value_name(S,find_name);
					 }break;
				 default : printf("输入的编号有误\n"); break;
				 }
				 }break;
		case 5:
			 {
				 int c;   //存放要实现功能编号
				 printf("1、按学号修改\n");
				 printf("2、按位置修改\n");
				 printf("3、按姓名修改\n");
				 printf("请输入想要实现的功能编号>>");
				 scanf("%d",&c);
                 //使用switch语句实现对修改条件的变化
				 switch(c)
				 {
				 case 1:      //以学号为条件来特定修改特定信息
					 {
						 int old_id;
						 printf("请输入原id>>");
						 scanf("%d",&old_id);
						 printf("请输入修改的值\n");
						 datatype new_e = info_add();
						 list_update_value_id(S,old_id,new_e);
					 }break;
				 case 2:     //以位置为条件来特定修改特定信息
					 {
						 int pos;
						 printf("请输入想要修改的位置>>");
						 scanf("%d",&pos);
						 printf("请输入修改的值\n");
						 datatype new_e = info_add();
						 list_update_pos(S,pos,new_e);
					 }break;
				 case 3:    //以姓名为条件来特定修改特定信息
					 {
						 char old_name[20];
						 printf("请输入原姓名>>");
						 scanf("%s",old_name);
						 printf("请输入修改的值\n");
						 datatype new_e = info_add();
						 list_update_name(S,old_name,new_e);
					 }break;
				 default : printf("输入的编号有误\n"); break;
				 }
		     }break;
		case 0:    //销毁表以及退出程序
			 {
				 list_delete_all(S);
				 S=NULL;
				 exit(0);
			 } break;
		default : printf("输入的编号有误,请重新输入!\n"); break;
		}
	}
		return 0;
}

2)主函数使用到的功能函数

1、嫁衣函数(主函数不会直接调用但其他功能函数会反复调用)——申请子结点、判空、数据的输入

//申请节点
Student * node_buy(datatype e)
{
	Student *p = (Student *)malloc(sizeof(Student));
	if(NULL == p)
	{
		printf("节点申请失败\n");
		return NULL;
	}
	p->data = e;
	p->next = NULL;
	return p;
}

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

//信息输入
datatype info_add()
{
	datatype val;
	printf("请输入姓名>>");
	scanf("%s",val.name);
	printf("请输入学号>>");
	scanf("%d",&val.id);
	printf("请输入分数>>");
	scanf("%f",&val.score);
	return val;
}

2、创建头节点并初始化

//创建
Student * create()
{
	//申请结点
	Student *p=(Student *)malloc(sizeof(Student));
	if(NULL==p)
	{
		printf("创建失败\n");
		return NULL;
	}
	//初始化
	p->len=0;
	p->next=NULL;
	printf("创建成功\n");
	return p;
}

3、遍历链表元素

//遍历
void list_show(Student *S)
{
	if(NULL==S || list_empty(S))
	{
		printf("表空,遍历失败\n");
		return;
	}
	printf("链表元素分别是:\n");
	Student *q = S->next;
	while(q != NULL)
	{
		printf("%s\t%d\t%.2f\n",q->data.name,q->data.id,q->data.score);
		q = q->next;
	}
}

4、为了保证链表元素存储的顺序使用尾部插入的方式增加元素

//尾插
int list_intsrt_tail(Student *S,datatype e)
{
    //判断逻辑
	if(NULL==S)
	{
		printf("所给的链表不合法\n");
		return -1;
	}
    //调用结点申请函数申请一个子结点
	Student *p = node_buy(e);
    //定义遍历指针定位到链表尾部
	Student *q = S;
	while(q->next != NULL)
	{
		q = q->next;
	}
    //尾插操作
	q->next = p;
    //表的变化
	S->len++;
	printf("信息已录入\n");
	return 0;
}

5、根据不同的条件来定位结点的所在位置

//按位置查找返回查找到的节点
Student *find_node(Student *S, int pos)
{
	if(NULL==S || pos<0 || pos>S->len)
	{
		printf("查找失败\n");
		return NULL;
	}
	Student *q = S;
	for(int i=1; i<=pos; i++)
	{
		q = q->next;
	}
	return q;
}

//按学号查找返回查找节点的前驱节点
Student *find_node_id(Student *S, int old_id)
{
	if(NULL==S)
	{
		printf("查找失败\n");
		return NULL;
	}
	Student *q = S;
	while(q->next->data.id!=old_id)
	{
		if(q->next==NULL)
		{
			printf("查找失败\n");
			return NULL;
		}
		q = q->next;
	}
	return q;
}

//按姓名查找返回查找节点的前驱节点
Student *find_node_name(Student *S, char old_name[])
{
	if(NULL==S)
	{
		printf("查找失败\n");
		return NULL;
	}
	Student *q = S;
	while(strcmp(old_name,q->next->data.name))
	{
		if(q->next==NULL)
		{
			printf("查找失败\n");
			return NULL;
		}
		q = q->next;
	}
	return q;
}

6、从头部删除节点

//头删
int list_delete_head(Student *S)
{
	//判断逻辑
	if(NULL==S || list_empty(S))
	{
		printf("删除失败\n");
		return -1;
	}
	//头删
	Student *p = S->next;   //标记
	S->next = p->next;       //孤立
	free(p);                 //踢开
	p=NULL;
	//表的变化
	S->len--;
	return 0;
}

7、根据条件调用5中不同的函数进行删除特定节点

//任意位置删
int list_delete_pos(Student *S,int pos)
{
    //判断逻辑
	if(NULL==S || list_empty(S))
	{
		printf("删除失败\n");
		return -1;
	}
	Student *q=find_node(S,pos-1);
	Student *p=q->next;
	q->next = p->next;
	free(p);
	p=NULL;
	S->len--;
	printf("删除成功\n");
	return 0;
}
//任意学号删
int list_delete_id(Student *S,int old_id)
{
	Student *q=find_node_id(S,old_id);
    //判断逻辑
	if(NULL==S || list_empty(S) || q==NULL)
	{
		printf("删除失败\n");
		return -1;
	}
	Student *p=q->next;
	q->next = p->next;
	free(p);
	p=NULL;
	S->len--;
	printf("删除成功\n");
	return 0;
}
//任意姓名删
int list_delete_name(Student *S,char old_name[])
{
	Student *q=find_node_name(S,old_name);
    //判断逻辑
	if(NULL==S || list_empty(S) || q==NULL)
	{
		printf("删除失败\n");
		return -1;
	}
	Student *p=q->next;
	q->next = p->next;
	free(p);
	p=NULL;
	S->len--;
	printf("删除成功\n");
	return 0;
}

8、根据不同的要求查找到特定的结点并输出其数据域中的数据

//按学号查找返回第一个查找成功的学生信息
int list_search_value_id(Student *S,int e)
{
	//判断逻辑
	if(NULL==S || list_empty(S))
	{
		printf("查找失败\n");
		return -1;
	}
	//定义遍历指针
	Student *q = S->next;
	//查找符合给定条件学生信息
	for(int i=1; i<=S->len; i++)
	{
		//判断是否符合条件
		if(q->data.id==e)
		{
			printf("%s的成绩为%.2f学号为%d\n",q->data.name,q->data.score,q->data.id);
			return i;
		}
		q=q->next;
	}
	printf("查找失败,未找到相对应的值\n");
	return 0;
}
//按成绩查找返回第一个查找成功的学生信息
int list_search_value_score(Student *S,int e)
{
	//判断逻辑
	if(NULL==S || list_empty(S))
	{
		printf("查找失败\n");
		return -1;
	}
	//定义遍历指针
	Student *q = S->next;
	//查找符合给定条件学生信息
	for(int i=1; i<=S->len; i++)
	{
		//判断是否符合条件
		if(q->data.score==e)
		{
			printf("%s的成绩为%.2f学号为%d\n",q->data.name,q->data.score,q->data.id);
			return i;
		}
		q=q->next;
	}
	printf("查找失败,未找到相对应的值\n");
	return 0;
}
//按姓名查找返回第一个查找成功的学生信息
int list_search_value_name(Student *S,char e[])
{
	//判断逻辑
	if(NULL==S || list_empty(S))
	{
		printf("查找失败\n");
		return -1;
	}
	//定义遍历指针
	Student *q = S->next;
	for(int i=1; i<=S->len; i++)
	{
		//判断是否符合条件
		if(strcmp(q->data.name,e)==0)
		{
			printf("%s的成绩为%.2f学号为%d\n",q->data.name,q->data.score,q->data.id);
			return i;
		}
		q=q->next;
	}
	printf("查找失败,未找到相对应的值\n");
	return 0;
}

9、根据不同的要求找到特定的结点并更新其数据域中的数据

//按位置修改
int list_update_pos(Student *S,int pos,datatype new_e)
{
    //判断逻辑
	if(NULL==S || list_empty(S))
	{
		printf("表不合法,修改失败\n");
		return -1;
	}
	if(pos<1 || pos>S->len)
	{
		printf("表中未有该位置\n");
		return -2;
	}
    //判断条件是否符合
	Student *q=S;
	for(int i=1; i<=pos; i++)
	{
		q=q->next;
	}
    //更新数据
	q->data=new_e;
	printf("修改成功\n");
	return 0;
}

//按学号修改
int list_update_value_id(Student *S,int old_id,datatype new_e)
{
	if(NULL==S || list_empty(S))
	{
		printf("表不合法,修改失败\n");
		return -1;
	}
	Student *q=S->next;
	while(q!=NULL)
	{
		if(q->data.id==old_id)
		{
			q->data=new_e;
			return 0;
		}
		q=q->next;
	}
	printf("未找到符合的值\n");
	return -2;
}

//按姓名修改
int list_update_name(Student *S,char old_name[],datatype new_e)
{
	if(NULL==S || list_empty(S))
	{
		printf("表不合法,修改失败\n");
		return -1;
	}
	Student *q=S->next;
	while(q!=NULL)
	{
		if(strcmp(old_name,q->data.name)==0)
		{
			q->data=new_e;
			return 0;
		}
		q=q->next;
	}
	printf("未找到符合的值\n");
	return -2;
}

10、销毁表(防止内存的占用)

//销毁表
void list_delete_all(Student *S)
{
	if(NULL==S)
	{
		return;
	}
	//不断调用头删,将节点进行删除
	while(S->next != NULL)
	{
		list_delete_head(S);
	}
	//将头节点释放
	free(S);
	S=NULL;
	printf("表销毁成功\n");
	return;
}

3)程序运行结果(部分)

创建成功
--------------------------------------------
-------欢迎使用学生信息管理系统-------------
1、增入学生信息
2、输出所有的学生信息
3、删除学生信息
4、查找学生信息
5、修改学生信息
0、退出程序
请输入想要实现的功能编号:1
开始输入信息(姓名处输入#表示信息输入完成)
请输入姓名>>aa
请输入学号>>2001
请输入分数>>86
信息已录入
请输入姓名>>bb
请输入学号>>2002
请输入分数>>88
信息已录入
请输入姓名>>cc
请输入学号>>2003
请输入分数>>89
信息已录入
请输入姓名>>dd
请输入学号>>87
请输入分数>>91
信息已录入
请输入姓名>>#
信息输入完成
--------------------------------------------
-------欢迎使用学生信息管理系统-------------
1、增入学生信息
2、输出所有的学生信息
3、删除学生信息
4、查找学生信息
5、修改学生信息
0、退出程序
请输入想要实现的功能编号:2
链表元素分别是:
aa	2001	86.00
bb	2002	88.00
cc	2003	89.00
dd	87	91.00
--------------------------------------------
-------欢迎使用学生信息管理系统-------------
1、增入学生信息
2、输出所有的学生信息
3、删除学生信息
4、查找学生信息
5、修改学生信息
0、退出程序
请输入想要实现的功能编号:3
1、按学号删除
2、按姓名删除
3、按位置删除
请输入想要实现的功能编号>>1
请输入想要删除的学号>>87
删除成功
--------------------------------------------
-------欢迎使用学生信息管理系统-------------
1、增入学生信息
2、输出所有的学生信息
3、删除学生信息
4、查找学生信息
5、修改学生信息
0、退出程序
请输入想要实现的功能编号:2
链表元素分别是:
aa	2001	86.00
bb	2002	88.00
cc	2003	89.00
--------------------------------------------
-------欢迎使用学生信息管理系统-------------
1、增入学生信息
2、输出所有的学生信息
3、删除学生信息
4、查找学生信息
5、修改学生信息
0、退出程序
请输入想要实现的功能编号:4
1、按学号查找
2、按分数查找
3、按姓名查找
请输入想要实现的功能编号>>2
请输入分数>>86
aa的成绩为86.00学号为2001
--------------------------------------------
-------欢迎使用学生信息管理系统-------------
1、增入学生信息
2、输出所有的学生信息
3、删除学生信息
4、查找学生信息
5、修改学生信息
0、退出程序
请输入想要实现的功能编号:5
1、按学号修改
2、按位置修改
3、按姓名修改
请输入想要实现的功能编号>>3
请输入原姓名>>cc
请输入修改的值
请输入姓名>>ff
请输入学号>>2003
请输入分数>>92
--------------------------------------------
-------欢迎使用学生信息管理系统-------------
1、增入学生信息
2、输出所有的学生信息
3、删除学生信息
4、查找学生信息
5、修改学生信息
0、退出程序
请输入想要实现的功能编号:2
链表元素分别是:
aa	2001	86.00
bb	2002	88.00
ff	2003	92.00
--------------------------------------------
-------欢迎使用学生信息管理系统-------------
1、增入学生信息
2、输出所有的学生信息
3、删除学生信息
4、查找学生信息
5、修改学生信息
0、退出程序
请输入想要实现的功能编号:0
表销毁成功

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

命如星火

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

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

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

打赏作者

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

抵扣说明:

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

余额充值