单链表简单学生信息管理系统(纯C语言实现)

大一,刚开始学数据结构,用c语言浅浅写了一个简单的学生信息管理系统

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Student
{
	int id;
	char name[10];
}Student;
typedef struct LNode
{
	Student stu;
	struct LNode *next;
}LNode,*LinkList;                //LNode等价于struct LNode,LinkList等价于struct LNode* ,即LinkList 与LNode* 两种写法等价,都是表示一个指向结构体的指针类型 
//创建单链表 
void initLinkList(LNode* list);   //list就是一个节点,函数头中的list均为形参,只是表示一个LNode类型的指针变量 
//录入数据 
void insertList(LNode* list);
//展示数据 
void showList(LNode* list);
//删除数据
void deleStudent(LNode* list);
//查找数据 
void getStudent(LNode* list,int i);
//根据学号查找学生数据
LNode* getStudentInform(LNode* list,int id);
//根据姓名查找学生数据
LNode* getStudentName(LNode* list,char name[10]); 
//删除最后元素 
void deleLastStudent(LNode* list); 
//后插操作
void insertFromLastById(LNode* list,int i);
//插入数据(按位插入)
void insertData(LNode* list); 
//插入数据(按学号插)
void insertNextNode(LNode* list); 
//插入数据(按姓名插)
void insertNextName(LNode* list);
//更新数据
void updataStudent(LNode* list,int i);

int main()
{
	LinkList list=(LinkList)malloc(sizeof(LNode));
	initLinkList(list);//创建单链表 
	while(1){
		printf("-------------------------------------------------------\n");
		printf("---------------------菜           单-------------------\n");
		printf("-------------------------------------------------------\n");
		printf("---------------------请输入操作序号:------------------\n");
		printf("---------------------1、录入学生信息-------------------\n");
		printf("---------------------2、展示学生信息-------------------\n");
		printf("---------------------3、删除学生信息-------------------\n");
		printf("---------------------4、查询学生信息-------------------\n");
		printf("---------------------5、修改学生信息-------------------\n");
		printf("---------------------6、插入学生信息-------------------\n");
		printf("---------------------0、退        出-------------------\n");
		printf("-------------------------------------------------------\n");
		int flag;
	scanf("%d",&flag);
	int i=0;
	switch(flag){
		case 0:
			printf("正在退出......\n");
			return 0;
		case 1:
			insertList(list);//录入数据 
			break;	
		case 2:
			showList(list);//展示数据
			break;
		case 3:
			deleStudent(list);//删除数据
			break;
		case 4:
			printf("请输入查找方式:\n");
			printf("1、按学号查找\n");
			printf("2、按姓名查找\n");
			scanf("%d",&i);
			if(i==1||i==2){
				getStudent(list,i);
			}else{
				printf("您输入的方式有误!\n");
			}
			i=0;
			break;
		case 5:
			printf("请输入修改方式:\n");
			printf("1、按学号修改\n");
			printf("2、按姓名修改\n");
			scanf("%d",&i);
			if(i==1||i==2){
				updataStudent(list,i);
			}else{
				printf("您输入的方式有误!\n");
			}
			i=0;
			break;
		case 6:	
			printf("请输入插入方式:\n");
			printf("1、按学号插入\n");
			printf("2、按姓名插入\n");
			printf("3、按位置插入\n");
			scanf("%d",&i);
			if(i==1){
				insertNextNode(list);//插入数据(按学号插) 
			}else if(i==2){
				insertNextName(list);//插入数据(按姓名插) 
			}else if(i==3){
				insertData(list);//插入数据(按位插入)
			}else{
				printf("您输入的方式有误!\n"); 
			}
			i=0;
			break;
		default:
			printf("您输入的操作序号有误!请重新输入!\n"); 
	} 
	}
	return 0;
}
//创建单链表 
void initLinkList(LNode* list)
{
	list->next=NULL;         //指针初始化 
}
//录入数据 
void insertList(LNode* list)
{
	LNode* r;     //定义尾指针 
	r=list;
	int n;
	printf("请输入要录入数据的个数:\n");
	scanf("%d",&n);
	printf("请输入要录入的学生的学号和姓名:\n");
	while(n--){                                    //循环进行n次 
		LNode* p=(LNode*)malloc(sizeof(LNode));   //malloc 函数返回的是 void * 类型, malloc的返回值是一个指向空间首地址的指针,如果分配成功,返回一个非空指针。因此要进行类型转换 
		if(p==NULL){                                //p是指向新创建的节点的指针 
			return;
		}
		scanf("%d%s",&p->stu.id,p->stu.name);        
		p->next=NULL;
		r->next=p;          //把p的指针域赋值为null,原来尾指针指向p,这样就将p成功链接到头指针后面了
		r=p;               //此时p就成了尾指针,把r地址修改成p 
	}
	printf("录入数据成功!\n"); 
}
//展示数据
void showList(LNode* list)
{
	if(list->next==NULL){
		printf("对不起,您没有输入数据!\n");
		return;
	}
	LNode* p=list->next;         // list->next中存放的是地址,只能将地址赋给一个指针变量 
	while(p!=NULL){
		printf("学号:%d,姓名:%s\n",p->stu.id,p->stu.name);
		p=p->next;
	}
	
}
//查找数据 
void getStudent(LNode* list,int i)
{
	if(list->next==NULL){
		printf("对不起,您没有输入数据!\n");
		return;
	}
	LNode* p=NULL;
	if(i==1){
	int id;
	printf("请输入要查找的学号:\n");
	scanf("%d",&id);
	p=getStudentInform(list,id);
	}else{
		printf("请输入要查找的姓名:\n");
		char name[10];
		scanf("%s",name);
		p=getStudentName(list,name);
	} 
	if(p){
		printf("查找成功!\n");
		printf("学号:%d,姓名:%s\n",p->stu.id,p->stu.name);
	}
} 
//根据学号查找学生数据
LNode* getStudentInform(LNode* list,int id)
{
	LNode* p=list->next;
	while(p!=NULL&&p->stu.id!=id){
		p=p->next;
	}
	if(p==NULL){
		printf("您输入的学号有误!\n");
	}
	return p;
}
//根据姓名查找学生数据
LNode* getStudentName(LNode* list,char name[10])
{
	LNode* p=list->next;
	while(p!=NULL&&strcmp(p->stu.name,name)!=0){
		p=p->next;
	}
	if(p==NULL){
		printf("您输入的姓名有误!\n");
	}
	return p;	
 } 
 
//删除数据
void deleStudent(LNode* list)
{
	if(list->next==NULL){
		printf("对不起,您没有输入数据!\n");
		return;
	}
	printf("请输入要删除的学生学号:\n");
	int id;
	scanf("%d",&id);
	//查找学生数据,根据学号,返回节点p
	LNode* p=getStudentInform(list,id);
	//如果删除的节点是最后一个就要遍历
	if(p->next==NULL){
		deleLastStudent(list);
		return;
	}
	LNode* q=p->next;         //q是指针,不是q是LNode类型,是q指向LNode类型的变量 
	p->stu=q->stu;           //删除的本质就是复制后一个节点的数据将要删除节点的数据覆盖,并将要删除节点的指针域改为指向后面第二个节点,相当于将后一个节点内容复制给要删除节点之后,跨过后一个节点,去连接后面第二个节点 
	/*q=q->next;q只是一个临时指针后面不会用到,这样写没用,要达到删除的效果应该修改p,为节省空间释放q(不必须)*/ 
	p->next=q->next;
	free(q);
	printf("删除成功!\n");
	showList(list); 
}

//删除最后元素 
void deleLastStudent(LNode* list)
{
	LNode* s=list;
	LNode* pt=s->next;              //采用双指针的办法 
	while(pt->next!=NULL){
		s=s->next;
		pt=s->next;
	}
	s->next=pt->next;
	printf("删除成功!\n"); 
	showList(list);              //因为在函数中还要再次用到指针变量 list,因此引入和 list完全等价的指针变量 s,从而使list的值保持不变 
}
//插入数据(按位插入)
void insertData(LNode* list)
{
	if(list->next==NULL){
		printf("对不起,您没有输入数据!\n");
		return;
	}
	printf("请输入要插入数据的位置:\n");
	int i;
	scanf("%d",&i);
	//创建函数进行后插操作
	insertFromLastById(list,i);
	showList(list); 
}
//后插操作
void insertFromLastById(LNode* list,int i)
{
	LNode* p=list;
	int j=0;
	while(p!=NULL&&j<i-1){
		p=p->next;
		j++;
	}
	if(p==NULL){
		printf("您输入的位置有误!\n");
		return; 
	}
	LNode* s=(LinkList)malloc(sizeof(LNode));
	printf("请输入要插入学生的学号和姓名:\n");
	scanf("%d%s",&s->stu.id,s->stu.name);
	s->next=p->next;
	p->next=s;
	printf("插入成功!\n"); 
}
//插入数据(按学号插)
void insertNextNode(LNode* list)
{
	if(list->next==NULL){
		printf("对不起,您没有输入数据!\n");
		return;
	}
	printf("请输入要在哪个学号后插入:\n");
	int id;
	scanf("%d",&id);
	LNode* p=getStudentInform(list,id);
	LNode* s=(LinkList)malloc(sizeof(LNode));
	printf("请输入要插入学生的学号和姓名:\n");
	scanf("%d%s",&s->stu.id,s->stu.name);
	s->next=p->next;
	p->next=s;
	printf("插入成功!\n");
	showList(list);
}
//插入数据(按姓名插)
void insertNextName(LNode* list)
{
	if(list->next==NULL){
		printf("对不起,您没有输入数据!\n");
		return;
	}
	printf("请输入要在哪个姓名后插入:\n");	
	char name[10];
	scanf("%s",name);
	LNode* p=getStudentName(list,name);
	LNode* s=(LinkList)malloc(sizeof(LNode));
	printf("请输入要插入学生的学号和姓名:\n");
	scanf("%d%s",&s->stu.id,s->stu.name);
	s->next=p->next;
	p->next=s;
	printf("插入成功!\n");
	showList(list);
}

//更新数据
void updataStudent(LNode* list,int i)
{
	if(list->next==NULL){
		printf("对不起,您没有输入数据!\n");
		return;
	}
	LNode* p=NULL;
	if(i==1){
		printf("请输入要更改的学生的学号:\n");
		int id;
		scanf("%d",&id);
		p=getStudentInform(list,id);
	}else{
		printf("请输入要更改的学生的姓名:\n");
		char name[10];
		scanf("%s",name);
		p=getStudentName(list,name); 
	}
	if(p){
		printf("请重新输入学生的学号和姓名:\n");
		scanf("%d%s",&p->stu.id,p->stu.name);
		printf("修改成功!\n");
		showList(list);
	}
	
}

有参考别人的写法,也加了自己的东西到里面,是一边写一边改进的,写到后面不想改了,所以删除只用了学号查找这一种方式

以及我没有考虑按姓名查找若有重名的情况,因此按姓名查询得到只有最前面符合条件的一条结果

还有就是录入姓名用的scanf,英文名有空格的情况就不适用

刚学,有瑕疵,且作分享,还请多多指教hhh

  • 8
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值