student.h
#ifndef __STUDENT_H__
#define __STUDENT_H__
typedef struct
{
int id; //学号
char name[20]; //姓名
float score; //成绩
char sex[5]; //性别
}datatype;
typedef struct Node
{
union
{
int num; //人数
datatype data; //数据
};
struct Node *next; //指针域
struct Node *prio;
}student;
//总菜单
void menu();
//创建
student *create();
//申请结点存储数据
student *node_buy();
//插入菜单
void insert_menu(student *S);
//头插
int list_insert_head(student *S);
//任意插
int list_insert_pos(student *S);
//尾插
int list_insert_tail(student *S);
//判空
int empty(student *S);
//遍历
void show(student *S);
//用位置返回结点
student *search_pos(student *S,int pos);
//查找人菜单
void search_menu(student *S);
//查找人(按姓名)
int list_search_name(student *S);
//查找人(按性别)
int list_search_sex(student *S);
//查找人(按学号)
int list_search_id(student *S);
//修改菜单
void modify_menu(student *S);
//按姓名修改数据
int modify_name(student *S);
//按学号修改数据
int modify_id(student *S);
//排序降序
void sort(student *S);
//删除菜单
void delete_menu(student *S);
//按姓名删
int delete_name(student *S);
//按学号删
int delete_id(student *S);
//头删
int delete_head(student *S);
//销毁链表
void destroy(student **S);
#endif
student.c文件
##1. 菜单函数
#include<stdlib.h>
#include"student.h"
#include<stdio.h>
#include<string.h>
int x=0; //x=0时,链表头结点置NULL
//student *tail=NULL;
//总菜单
void menu()
{
student *S; //链表头
if(x==0)
{
S=NULL;
}
system("clear"); //清屏
//主菜单
printf("--------学生信息管理系统--------\n");
printf("1.创建学生信息链表\n");
printf("2.插入数据\n");
printf("3.遍历数据\n");
printf("4.查找人\n");
printf("5.修改数据\n");
printf("6.按成绩降序排序\n");
printf("7.删除数据\n");
printf("8.销毁链表.\n");
printf("请输入选择功能的序号(或按q或Q退出系统):");
char choice;
scanf("%c",&choice);
getchar();
printf("\n\n");
//判断是否退出程序
if(choice=='Q' || choice=='q')
{
printf("--------已退出系统--------------\n");
exit(0);
}
//除选项1外,判断链表是否创建
if(S==NULL && choice != '1')
{
printf("请先创建链表\n\n\n");
printf("-------按回车键返回主菜单\n");
getchar(); //保证输出可见
return;
}
//防止链表再被创建一遍,造成数据丢失,内存泄露
if(S!=NULL && choice == '1')
{
printf("链表已经创建,无法再次创建\n\n\n");
printf("-------按回车键返回主菜单\n");
getchar(); //保证输出可见
return;
}
//判断选择
switch(choice)
{
case '1': S=create();
break;
case '2':insert_menu(S);
break;
case '3':show(S);
break;
case '4':search_menu(S);
break;
case '5':modify_menu(S);
break;
case '6':sort(S);
break;
case '7':delete_menu(S);
break;
case '8':destroy(&S);
break;
default:
{
printf("\n\n功能序号输入错误,请重试!\n");
printf("-------按回车键返回主菜单\n");
getchar(); //保证输出可见
return;
}
}
printf("\n\n--------功能已完成,请按回车键返回主菜单\n");
getchar();
}
创建函数
//创建
student *create()
{
student *S=(student *)malloc(sizeof(student));
//判断逻辑
if(NULL==S)
{
printf("创建链表失败\n");
return NULL;
}
//初始化
S->num=0;
S->next=NULL;
S->prio=NULL;
x=1;
printf("链表创建成功\n");
return S;
}
申请结点存储数据
//申请结点存储数据
student *node_buy()
{
student *p=(student *)malloc(sizeof(student));
//判断逻辑
if(NULL==p)
{
printf("申请结点失败\n");
return NULL;
}
//输入数据
datatype e;
printf("\n请输入学生数据\n");
printf("学号:");
scanf("%d",&e.id);
printf("姓名:");
scanf("%s",e.name);
printf("成绩:");
scanf("%f",&e.score);
printf("性别:");
scanf("%s",e.sex);
//存储数据
p->next=NULL;
p->prio=NULL;
p->data=e;
// printf("申请结点存储数据成功\n");
return p;
}
插入菜单
//插入菜单
void insert_menu(student *S)
{
while(1)
{
system("clear");//清屏
//菜单
printf("---------插入菜单\n");
printf("1.头插\n");
printf("2.任意插\n");
printf("3.尾插\n");
printf("请输入选择功能的序号:");
//输入选项
char choice;
scanf("%c",&choice);
getchar();
//与default同功能
// if(choice==[^1-3])
// {
// printf("\n功能序号输入错误,请重试!\n\n");
// continue;
// }
//根据选择,提供不同的反应
switch(choice)
{
case '1': list_insert_head(S);
break;
case '2': list_insert_pos(S);
break;
case '3': list_insert_tail(S);
break;
default:
{
printf("\n功能序号输入错误,请重试!\n");
printf("-------按回车键返回插入菜单\n");
getchar();//保证输出可见
continue;
}
}
break; //退出循环
}
getchar();
}
头插
//头插
int list_insert_head(student *S)
{
char choice='1';
do
{
system("clear");
//申请结点存储数据
student *p=node_buy();
if(NULL==p)
{
printf("头插失败\n");
return -1;
}
//头插
if(S->next==NULL) //链表无数据
{
S->next=p;
p->prio=S;
}
else //链表有数据
{
p->next=S->next;
p->prio=S;
S->next->prio=p;
S->next=p;
}
printf("头插成功\n\n");
S->num++;
getchar(); //吸收换行
printf("是否继续插入数据(输入'y'或'Y'继续插入):");
scanf("%c",&choice);
}while(choice=='y' || choice=='Y');
return 0;
}
任意插
//任意插
int list_insert_pos(student *S)
{
char choice='y';
do
{
system("clear");
printf("\n请输入要插入的位置:");
int pos;
scanf("%d",&pos);
printf("\n");
//查找插入结点的前驱
student *q=search_pos(S,pos-1);
printf("\n");
//判断逻辑
if(q==NULL)
{
printf("-------按换行键返回插入菜单\n\n");
getchar();
getchar();
continue;
}
//申请结点存储数据
student *p=node_buy();
if(NULL==p)
{
printf("任意插失败\n");
return -1;
}
if(pos==S->num+1)
{
p->prio=q;
q->next=p;
}
else
{
p->prio=q;
p->next=q->next;
q->next->prio=p;
q->next=p;
}
printf("任意插成功\n\n");
S->num++;
getchar(); //吸收换行
printf("是否继续插入数据(输入'y'或'Y'继续插入):");
scanf("%c",&choice);
}while(choice=='y' || choice=='Y');
return 0;
}
尾插
//尾插
int list_insert_tail(student *S)
{
char choice;
do
{
system("clear");
//申请结点存储数据
student *p=node_buy();
if(NULL==p)
{
printf("尾插失败\n");
return -1;
}
//尾插
student *q=S;
while(q->next!=NULL)
{
q=q->next;
}
q->next=p;
p->prio=q;
printf("尾插成功\n\n");
S->num++;
getchar(); //吸收换行
printf("是否继续插入数据(输入'y'或'Y'继续插入):");
scanf("%c",&choice);
}while(choice=='y' || choice=='Y');
return 0;
}
判空
//判空
int empty(student *S)
{
return S->next==NULL ?1:0; //1为空,0为非空
}
遍历
//遍历
void show(student *S)
{
//判断逻辑
if(empty(S))
{
printf("链表为空.遍历失败\n");
return;
}
//遍历
printf("学生信息如下\n");
printf("\t学号\t姓名\t性别\t成绩\n");
student *q=S->next;
while(q!=NULL)
{
printf("\t%d\t%s\t%s\t%.2f\n"
,q->data.id,q->data.name,q->data.sex,q->data.score);
q=q->next;
}
}
用位置返回结点
//用位置返回结点
student *search_pos(student *S,int pos)
{
//判断逻辑
if(pos<1 ||pos>S->num+1)
{
printf("输入位置不合法,请重试\n");
return NULL;
}
//查找结点
student *q=S;
for(int i=1;i<=pos;i++)
{
q=q->next;
}
student *p=q;
return p;
}
查找人菜单
//查找人菜单
void search_menu(student *S)
{
//判断逻辑
if(empty(S))
{
printf("链表为空,无法查找\n");
return;
}
while(1)
{
system("clear");//清屏
//菜单
printf("---------查找人菜单\n");
printf("1.查找人(按姓名)\n");
printf("2.查找人(按性别)\n");
printf("3.查找人(按学号)\n");
printf("请输入选择功能的序号:");
//输入选项
char choice;
scanf("%c",&choice);
getchar();
switch(choice)
{
case '1':list_search_name(S);
break;
case '2':list_search_sex(S);
break;
case '3':list_search_id(S);
break;
default:
{
printf("\n功能序号输入错误,请重试!\n");
printf("-------按回车键返回插入菜单\n");
getchar();//保证输出可见
continue;
}
}
break; //跳出循环
}
}
查找人(按姓名)
//查找人(按姓名)
int list_search_name(student *S)
{
int a=0;
printf("\n请输入查找的学生姓名:");
char n[20];
scanf("%s",n);
student *q=S->next;
while(q!=NULL)
{
if(strcmp(n,(q->data).name)==0)
{
if(a==0)
{
printf("\n找到学生,其详细信息如下\n");
printf("\t学号\t姓名\t性别\t成绩\n");
}
printf("\t%d\t%s\t%s\t%.2f\n"
,q->data.id,q->data.name,q->data.sex,q->data.score);
a=1;
}
q=q->next;
}
if(q==NULL && a==0)
{
printf("未找到该学生\n");
}
getchar();
}
查找人(按性别)
//查找人(按性别)
int list_search_sex(student *S)
{
int a=0;
printf("\n请输入查找的学生性别:");
char n[5];
scanf("%s",n);
student *q=S->next;
while(q!=NULL)
{
if(strcmp(n,(q->data).sex)==0)
{
if(a==0)
{
printf("\n找到学生,其详细信息如下\n");
printf("\t学号\t姓名\t性别\t成绩\n");
}
printf("\t%d\t%s\t%s\t%.2f\n"
,q->data.id,q->data.name,q->data.sex,q->data.score);
a=1;
}
q=q->next;
}
if(q==NULL && a==0)
{
printf("未找到该学生\n");
}
getchar();
}
查找人(按学号)
//查找人(按学号)
int list_search_id(student *S)
{
int a=0;
printf("\n请输入查找的学生学号:");
int n;
scanf("%d",&n);
student *q=S->next;
while(q!=NULL)
{
if(n==q->data.id)
{
if(a==0)
{
printf("\n找到学生,其详细信息如下\n");
printf("\t学号\t姓名\t性别\t成绩\n");
}
printf("\t%d\t%s\t%s\t%.2f\n"
,q->data.id,q->data.name,q->data.sex,q->data.score);
a=1;
}
q=q->next;
}
if(q==NULL && a==0)
{
printf("未找到该学生\n");
}
getchar();
}
修改菜单
//修改菜单
void modify_menu(student *S)
{
//判断逻辑
if(empty(S))
{
printf("链表为空,无法修改\n");
return;
}
while(1)
{
system("clear");//清屏
//菜单
printf("---------修改菜单\n");
printf("1.按姓名修改数据\n");
printf("2.按学号修改数据\n");
printf("请输入选择功能的序号:");
//输入选项
char choice;
scanf("%c",&choice);
getchar();
//根据选择,提供不同的反应
switch(choice)
{
case '1': modify_name(S);
break;
case '2': modify_id(S);
break;
default:
{
printf("\n功能序号输入错误,请重试!\n");
printf("-------按回车键返回插入菜单\n");
getchar();//保证输出可见
continue;
}
}
break; //退出循环
}
getchar();
}
按姓名修改数据
//按姓名修改数据
int modify_name(student *S)
{
printf("\n请输入修改的学生姓名:");
char n[20];
scanf("%s",n);
student *q=S->next;
while(q!=NULL)
{
if(strcmp(n,(q->data).name)==0)
{
printf("\n找到学生\n");
//输入数据
datatype e;
printf("\n请输入修改的学生数据\n");
printf("学号:");
scanf("%d",&e.id);
printf("姓名:");
scanf("%s",e.name);
printf("成绩:");
scanf("%f",&e.score);
printf("性别:");
scanf("%s",e.sex);
q->data=e;
printf("\n");
break;
}
q=q->next;
}
if(q==NULL)
{
printf("未找到该学生\n");
}
}
按学号修改数据
//按学号修改数据
int modify_id(student *S)
{
printf("\n请输入修改的学生学号:");
int n;
scanf("%d",&n);
student *q=S->next;
while(q!=NULL)
{
if(n==q->data.id)
{
printf("\n找到学生\n");
//输入数据
datatype e;
printf("\n请输入修改的学生数据\n");
printf("学号:");
scanf("%d",&e.id);
printf("姓名:");
scanf("%s",e.name);
printf("成绩:");
scanf("%f",&e.score);
printf("性别:");
scanf("%s",e.sex);
q->data=e;
printf("\n");
break;
}
q=q->next;
}
if(q==NULL)
{
printf("未找到该学生\n");
}
}
按成绩降序排序
//按成绩降序排序
void sort(student *S)
{
//判断逻辑
if(empty(S))
{
printf("链表为空,无法排序\n");
return;
}
//排序
int i,j;
for(i=1;i<S->num;i++)
{
for(j=0;j<S->num-i;j++)
{
student *p=search_pos(S,j+1);
student *q=search_pos(S,j+2);
if(p->data.score<q->data.score)
{
if(q->next==NULL)
{
p->next=q->next;
q->prio=p->prio;
q->next=p;
p->prio->next=q;
p->prio=q;
}
else
{
p->next=q->next;
q->prio=p->prio;
p->prio->next=q;
q->next->prio=p;
q->next=p;
p->prio=q;
}
}
}
}
printf("排序成功\n");
}
删除菜单
//删除菜单
void delete_menu(student *S)
{
if(empty(S))
{
printf("链表为空,无法删除\n");
return;
}
while(1)
{
system("clear");//清屏
//菜单
printf("---------删除菜单\n");
printf("1.按姓名删\n");
printf("2.按学号删\n");
printf("3.头删\n");
printf("请输入选择功能的序号:");
//输入选项
char choice;
scanf("%c",&choice);
getchar();
switch(choice)
{
case '1': delete_name(S);
break;
case '2': delete_id(S);
break;
case '3':delete_head(S);
break;
default:
{
printf("\n功能序号输入错误,请重试!\n");
printf("-------按回车键返回插入菜单\n");
getchar();//保证输出可见
continue;
}
}
break; //退出循环
}
getchar();
}
按姓名删
//按姓名删
int delete_name(student *S)
{
printf("\n请输入修改的学生姓名:");
char n[20];
scanf("%s",n);
student *q=S->next;
while(q!=NULL)
{
if(strcmp(n,(q->data).name)==0)
{
printf("\n找到学生\n");
if(q->next==NULL) //判断是否为尾节点
{
q->prio->next=NULL;
free(q);
q=NULL;
}
else
{
q->prio->next=q->next;
q->next->prio=q->prio;
free(q);
q=NULL;
}
printf("删除成功\n");
S->num--;
return 0;
}
q=q->next;
}
if(q==NULL)
{
printf("未找到该学生\n");
}
}
按学号删
//按学号删
int delete_id(student *S)
{
printf("\n请输入修改的学生学号:");
int n;
scanf("%d",&n);
student *q=S->next;
while(q!=NULL)
{
if(n==q->data.id)
{
printf("\n找到学生\n");
if(q->next==NULL) //判断是否为尾节点
{
q->prio->next=NULL;
free(q);
q=NULL;
}
else
{
q->prio->next=q->next;
q->next->prio=q->prio;
free(q);
q=NULL;
}
printf("删除成功\n");
S->num--;
return 0;
}
q=q->next;
}
if(q==NULL)
{
printf("未找到该学生\n");
}
}
头删
//头删
int delete_head(student *S)
{
student *q=S->next;
if(q->next==NULL)
{
S->next=NULL;
}
else
{
S->next=q->next;
q->next->prio=S;
}
free(q);
q=NULL;
printf("\n头删成功\n");
S->num--;
return 0;
}
销毁链表
//销毁链表
void destroy(student **S)
{
while((*S)->next!=NULL)
{
//头删
delete_head(*S);
}
free(*S);
*S=NULL;
printf("链表销毁成功\n");
}
主函数 main.c
#include<stdlib.h>
#include<string.h>
#include"student.h"
#include<stdio.h>
int main(int argc, const char *argv[])
{
while(1)
{
menu();
}
return 0;
}