结构体定义:
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;ilen-1;i++)
{
q = L->next; //每一轮排序开始前都要将遍历指针指回第一个结点
for(int j=0;jlen-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;ilen-1;i++)
{
q = L->next;
for(int j=0;jlen-i-1;j++)
{
if(q->data.idnext->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;ilen-1;i++)
{
q = L->next;
for(int j=0;jlen-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;ilen-1;i++)
{
q = L->next;
for(int j=0;jlen-i-1;j++)
{
if(q->data.scorenext->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.退出系统