使用链表完成简易的学生管理系统
无非就是增删改查
用时半天,写了一个简易版
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void show(void);
typedef struct student
{
int m_id;
char m_name[64];
double m_chinese;
double m_math;
double m_english;
struct student * next;
}STU;
STU * head = NULL;
STU * insert_link(STU * head,STU tmp);
void printf_link(STU * head);
void find_link(STU * head,int id);
STU * delete_link(STU * head,int id);
void change_link(STU * head,int id);
int main(int argc, char *argv[])
{
show();
while(1)
{
char chose[64]="";
fgets(chose,sizeof(chose),stdin);
chose[strlen(chose)-1] = '\0';
printf("您的选择为:%s\n",chose);
if(strcmp("add",chose)==0)
{
printf("增加\n");
STU tmp;
printf("请输入添加的学生的id\n");
scanf("%d",&tmp.m_id);
printf("请输入添加的学生的姓名\n");
scanf("%s",tmp.m_name);
printf("请输入添加的学生的语文成绩\n");
scanf("%lf",&tmp.m_chinese);
printf("请输入添加的学生的数学成绩\n");
scanf("%lf",&tmp.m_math);
printf("请输入添加的学生的英语成绩\n");
scanf("%lf",&tmp.m_english);
//printf("%5.2f %5.2f %5.2f\n",tmp.m_chinese,tmp.m_math,tmp.m_english);
getchar();
head = insert_link(head,tmp);
continue;
}
else if(strcmp("delete",chose)==0)
{
int id=0;
printf("请输入要删除的ID\n");
scanf("%d",&id);
head = delete_link(head,id);
}
else if(strcmp("change",chose)==0)
{
//更改信息
int id;
printf("请输入要修改的id为:");
scanf("%d",&id);
change_link(head,id);
}
else if(strcmp("find",chose)==0)
{
int id;
printf("请输入要查找的ID编号\n");
scanf("%d",&id);
find_link(head,id);
continue;
}
else if(strcmp("show",chose)==0)
{
printf_link(head);
}
else if(strcmp("out",chose)==0)
{
printf("退出\n");
exit(0);
}
else if(strcmp("",chose)==0)//如果按下回车键,那么就不会打印其它的
{
;
}
else
{
printf("您的输入有误,请重新输入!\n");
}
}
return 0;
}
void show(void)
{
printf("**********************************************************\n");
printf("*********** 学生管理系统 *************\n");
printf("***********************add.增加信息***********************\n");
printf("***********************delete.删除信息********************\n");
printf("***********************change.更改信息********************\n");
printf("***********************find.查找信息**********************\n");
printf("***********************show.打印信息**********************\n");
printf("***********************out.退出系统***********************\n");
printf("**********************************************************\n");
}
STU *insert_link(STU * head,STU tmp)
{
//为插入的节点申请空间
STU * pi = (STU *)calloc(1,sizeof(STU));
//给这个新开辟的空间赋值
*pi = tmp;
//将结构体中的next指向NULL
pi ->next = NULL;
//判断链表中是不是有值
if(NULL == head)
{
head = pi;
}
else
{
//此时链表中有内容
pi->next = head;
head = pi;
}
return head;
}
void printf_link(STU * head)
{
//首先判断这个head是不是为空,链表是不是为空
if(NULL == head)
{
printf("链表为空!\n");
return;
}
else
{
STU * pi = head;
while(pi != NULL)
{
printf("该生名为:%s 学号:%d 语文成绩:%5.2lf 数学成绩为:%5.2lf 英语成绩为:%5.2lf\n",pi->m_name,pi->m_id,pi->m_chinese,pi->m_math,pi->m_english);
pi = pi->next;
}
}
return ;
}
void find_link(STU * head,int id)
{
//设置一个标志,用来标记有没有找到
int flag = 0;
//首先依然是判断这个链表是不是为空
if(NULL == head)
{
printf("链表为空!\n");
}
else
{
//定义一个指针,用来保存head的地址,操作的时候,不要改变head的值
STU * pi = head;
//便利链表查找这个id
printf("进入查询链表中了\n");
while(pi != NULL)
{
if(id == pi->m_id)
{
flag++;
printf("找到这个人的了,它的信息为:\n");
printf("该生名为:%s 学号:%d 语文成绩:%5.2lf 数学成绩为:%5.2lf 英语成绩为:%5.2lf\n",pi->m_name,pi->m_id,pi->m_chinese,pi->m_math,pi->m_english);
}
pi = pi->next;
}
if(flag == 0)
{
printf("查无此人\n");
}
}
return ;
}
STU * delete_link(STU * head,int id)
{
//首先还是判断链表是不是为空
if(NULL == head)
{
printf("链表为空\n");
return head;
}
else
{
STU * pi = head;
STU * pb = head;
//寻找删除点,两者均为真才会是一前一后的,如果找到需要删除的id或者是已经到最后了才会退出
while((pb->m_id != id) && (pb->next != NULL))
{
pi = pb;
pb = pb->next;
}
//检测是不是因为找到相同的IP而退出
if(pb->m_id == id)
{
//还要看,这个要删除的IP是不是第一个,如果是第一个,那么head的值就会被改变
if(head == pb)
{
head = head->next;
printf("删除成功!\n");
}
else
{
//如果要删除的是中间或者尾部,那就好说了
//将前一个的指针,指向后一个的下一个,那么中间这个一个就被跳过去了
pi->next = pb->next;
printf("删除成功!\n");
}
//这个上面的操作只是链表将这个要删除的节点跳过了,下面真正删除它
if(pb != NULL)
{
//释放pb所指向的堆区空间
free(pb);
//虽然释放了pb所指向堆区的空间,但是pb本身还是有值的,要将这个值置成NULL
pb = NULL;
}
//不管是哪一种删除,只要能够找到,那就是删除成功了
}
//还有一种退出的可能
else if(pb->next == NULL)
{
//到最后都没有找到这个ip,那么就是没有找到
printf("没有找到这个ID\n");
}
}
//链表的有有可能被改变,所有要返回被改变的链表头部
return head;
}
void change_link(STU * head,int id)
{
STU * pb = head;
float chinese;
float math;
float english;
char name[32] = "";
int flag = 0;
//首先遍历整个链表,找到指定的ip
while(pb!=NULL)
{
if(pb->m_id == id)
{
printf("请修改%s的语文成绩为:",pb->m_name);
scanf("%lf",&pb->m_chinese);
printf("请修改%s的数学成绩为:",pb->m_name);
scanf("%lf",&pb->m_math);
printf("请修改%s的英语成绩为:",pb->m_name);
scanf("%lf",&pb->m_english);
flag++;
return ;
}
pb = pb->next;
}
if(flag == 0)
{
printf("没有找到ID为%d的学生信息\n");
}
return ;
}
再写链表之前,仔细思考每一个节点应该如何去设计,然后这此我写链表的时候,时间匆忙,链表节点的插入只是采用了头插发,可以对这个方面进行改进,可以是以学号进行排序,有序的排序,这个在查找的时候会更加便捷,我这个链表是采用遍历的方法,挺傻的