基于链表的学生管理系统

  • 基于链表的学生管理系统
    • 前言
    • 功能
    • 整体思路
      • Function.h
      • Function.cpp
      • 主文件StudentManageSystem.cpp
    • 各函数详细说明
      • 保存
      • 读取
      • 查找
      • 添加
      • 添加列表
      • 修改
      • 链表有序归并(为链表排序函数做基础)
      • 链表排序
      • 输出
      • 帮助菜单
      • 主函数

基于链表的学生管理系统

前言

快到大一期末了,C语言课也结课了,期末作业学生管理系统,在写代码的过程中在老师讲课的基础上再加上一些创新的地方,前前后后写代码改bug差不多三四天,没想到居然写成了,收获了许多经验。二话不多说直接上代码,记得点赞收藏!

功能

  1. 通过文件导入到程序链表
  2. 通过程序链表保存到文件
  3. 主菜单显示
  4. 输入学生列表信息
  5. 添加学生列表
  6. 添加单个学生信息
  7. 修改某个学生信息
  8. 删除某个学生信息
  9. 对学生的学生成绩排序并输出
  10. 对学生的学生学号排序并输出

整体思路

利用链表建立,添加,删除来对信息的读入和输出
利用链表的归并排序算法(速度快)来对链表进行排序
增加一些容错机制,,,
通过函数模块化来对项目进行管理
通过主菜单help()函数来囊括所有函数
XD

Function.h

#pragma once/***************
* 学生数据
* 编号 id
* 姓名 name
* 分数 score
* 下一个学生数据
****************/
struct Person
{int id;char name[20];int score;struct Person* next;
};//链表存入文件
void saveFile();//文件读取数据到链表
struct Person* loadFile();//主菜单显示
int help();//查询某个学生信息
void searchInfo();//修改某个学生信息
void modifyInfo();//将两个学生信息列表按成绩有序归并
struct Person* mergeScoreList(struct Person* node1, struct Person* node2);//将两个学生信息列表按学号有序归并
struct Person* mergeIdList(struct Person* node1, struct Person* node2);//将学生信息按成绩排序
struct Person* sortScoreList(struct Person* head);//将学生信息按学号排序
struct Person* sortIdList(struct Person* head);//删除学生信息
void deleteInfo();//添加学生信息
void addInfo();//添加学生信息列表
void addInfoList();//展示学生信息列表
void displayList();

Function.cpp

#include "Function.h"#include <stdio.h>
#include <stdlib.h>
#include <string.h>extern struct Person* head;void saveFile()
{FILE* fp;struct Person* p1 = head;if ((fp = fopen("Student.txt", "w")) == NULL){printf("File set failed!\n");return;}while (p1 != NULL){fprintf(fp, "%d\t%s\t%d\n", p1->id, p1->name, p1->score);p1 = p1->next;}fclose(fp);
}struct Person* loadFile()
{int i = 0;char tname[20];int tid;int tscore;FILE* fp;Person* p1 = NULL;Person* p2 = NULL;Person* head = NULL;if ((fp = fopen("Student.txt", "r")) == NULL){printf("File set failed!\n");return NULL;}while (fscanf(fp, "%d%s%d", &tid, tname, &tscore) != EOF){p1 = (Person*)malloc(sizeof(Person));p1->next = NULL;p1->id = tid;strcpy(p1->name, tname);p1->score = tscore;if (i == 0){head = p1;p2 = p1;i = 1;}else{p2->next = p1;p2 = p1;}}return head;
}void searchInfo()
{int tid;struct Person* p1 = head;printf("宁要查询的学生学号为?\n");scanf("%d", &tid);while (p1 != NULL){if (p1->id == tid){printf("学号\t姓名\t成绩\n");printf("%d\t%s\t%d\n", p1->id, p1->name, p1->score);break;}p1 = p1->next;}if (p1 == NULL)printf("未找到该学号!\n");
}void deleteInfo()
{int tid;int i;char tch;struct Person* p1 = head;struct Person* tp = head;printf("您要删除的学生学号为?\n");scanf("%d", &tid);getchar();for (i = 0;; i++){if (i == 0 && p1->id == tid){printf("确定删除姓名为 %s 的信息?(Y\\N)\n", p1->name);tch = getchar();getchar();if (tch == 'Y'){head = head->next;free(p1);printf("删除成功\n");break;}else{printf("删除失败\n");break;}}if (p1 == NULL){printf("未找到该学号\n");}if (p1->id == tid){printf("确定删除姓名为 %s 的信息?(Y\\N)\n", p1->name);tch = getchar();getchar();if (tch == 'Y'){tp->next = p1->next;free(p1);printf("删除成功\n");break;}else{printf("删除失败\n");break;}}if (i != 0){tp = tp->next;}p1 = p1->next;}
}void addInfo()
{char tch;struct Person* node = (Person*)malloc(sizeof(Person));struct Person* tp = head;printf("输入添加学生的学号:");scanf("%d", &node->id);while (tp != NULL){if (tp->id == node->id){printf("该学号已存在\n");return;}tp = tp->next;}printf("输入添加学生的姓名:");scanf("%s", node->name);printf("输入添加学生的成绩:");scanf("%d", &node->score);getchar();printf("是否撤销刚刚的操作?(Y\\N)");tch = getchar();if (tch == 'Y'){printf("操作已撤销\n");return;}node->next = head;head = node;printf("添加成功\n");
}void addInfoList()
{char tch;int tid;char tname[20];int tscore;struct Person* tp = NULL;struct Person* p1 = head;printf("输入学生列表:\n输入学号为0表示输入结束\n");for (int i = 1;; i++){tp = (struct Person*)malloc(sizeof(Person));printf("输入第 %d 个学生的学号:", i);scanf("%d", &tid);if (tid == 0){free(tp);tp = NULL;printf("录入学生信息结束,共录入 %d 个学生信息\n", i - 1);return;}while (p1 != NULL){if (p1->id == tid){printf("该学号已存在\n");return;}p1 = p1->next;}printf("输入第 %d 个学生的姓名:", i);scanf("%s", tname);printf("输入第 %d 个学生的成绩:", i);scanf("%d", &tscore);tp->id = tid;strcpy(tp->name, tname);tp->score = tscore;tp->next = head;head = tp;}
}void modifyInfo()
{int tid;struct Person* p1 = head;printf("输入修改的学生学号:");scanf("%d", &tid);while (p1 != NULL){if (p1->id == tid){printf("学生信息\n学号\t姓名\t成绩\n");printf("%d\t%s\t%d\n", p1->id, p1->name, p1->score);printf("修改姓名为:");scanf("%s", p1->name);printf("修改成绩为:");scanf("%d", &p1->score);printf("信息修改成功\n");break;}p1 = p1->next;}if (p1 == NULL)printf("未找到该学号\n");
}struct Person* mergeIdList(struct Person* node1, struct Person* node2)
{if (node1 == NULL)return node2;if (node2 == NULL)return node1;if (node1->id < node2->id){node1->next = mergeIdList(node1->next, node2);return node1;}if (node1->id >= node2->id){node2->next = mergeIdList(node1, node2->next);return node2;}
}struct Person* sortIdList(struct Person* node)
{struct Person* p1 = node;struct Person* p2 = node;struct Person* tp = node;struct Person* tp2 = NULL;struct Person* tp1 = NULL;if (node->next == NULL)return node;for (int i = 0; p1 != NULL && p1->next != NULL; i++){p1 = p1->next->next;p2 = p2->next;if (i != 0)tp = tp->next;}tp->next = NULL;tp2 = sortIdList(p2);tp1 = sortIdList(node);return mergeIdList(tp1, tp2);
}struct Person* mergeScoreList(struct Person* node1, struct Person* node2)
{if (node1 == NULL)return node2;if (node2 == NULL)return node1;if (node1->score < node2->score){node1->next = mergeScoreList(node1->next, node2);return node1;}if (node1->score >= node2->score){node2->next = mergeScoreList(node1, node2->next);return node2;}
}struct Person* sortScoreList(struct Person* node)
{struct Person* p1 = node;struct Person* p2 = node;struct Person* tp = node;struct Person* tp2 = NULL;struct Person* tp1 = NULL;if (node->next == NULL)return node;for (int i = 0; p1 != NULL && p1->next != NULL; i++){p1 = p1->next->next;p2 = p2->next;if (i != 0)tp = tp->next;}tp->next = NULL;tp2 = sortScoreList(p2);tp1 = sortScoreList(node);return mergeScoreList(tp1, tp2);
}void displayList()
{struct Person* p1 = head;printf("学号\t姓名\t成绩\n");while (p1 != NULL){printf("%d\t%s\t%d\n", p1->id, p1->name, p1->score);p1 = p1->next;}
}int help()
{char choice;printf("***************************************************************\n");printf("*                        学生管理系统                         *\n");printf("*输出成绩升序列表       输入:A                               *\n");printf("*输出学号升序列表       输入:B                               *\n");printf("*添加新的学生信息列表   输入:C                               *\n");printf("*添加新的学生信息       输入:D                               *\n");printf("*修改学生信息           输入:E                               *\n");printf("*查询学生信息           输入:F                               *\n");printf("*删除学生信息           输入:G                               *\n");printf("*退出菜单界面并保存     输入:H                               *\n");printf("*                                                             *\n");printf("*                                                             *\n");printf("***************************************************************\n");scanf("%c", &choice);system("CLS");switch (choice){case 'A':head = sortScoreList(head); displayList(); break;case 'B':head = sortIdList(head); displayList(); break;case 'C':addInfoList(); break;case 'D':addInfo(); break;case 'E':modifyInfo(); break;case 'F':searchInfo(); break;case 'G':deleteInfo(); break;case 'H':saveFile(); return 0;default:return 1;}return 1;
}

主文件StudentManageSystem.cpp

#include <stdio.h>
#include <windows.h>
#include "Function.h"struct Person* head = NULL;int main()
{head = loadFile();while (help()){system("pause");getchar();system("CLS");}return 0;
}

各函数详细说明

保存

通过fp文件指针打开文件,利用p1指针从链表开头遍历到结尾,每次遍历一个元素都将链表信息保存到文件当中

void saveFile()
{FILE* fp;struct Person* p1 = head;if ((fp = fopen("Student.txt", "w")) == NULL){printf("File set failed!\n");return;}while (p1 != NULL){fprintf(fp, "%d\t%s\t%d\n", p1->id, p1->name, p1->score);p1 = p1->next;}fclose(fp);
}

读取

用文件指针用只读的方式打开文件,p1从堆区开辟空间,将文件的信息读入到p1指针中,循环开辟链表,返回链表的头指针

struct Person* loadFile()
{int i = 0;char tname[20];int tid;int tscore;FILE* fp;struct Person* p1 = NULL;struct Person* p2 = NULL;struct Person* head = NULL;if ((fp = fopen("Student.txt", "r")) == NULL){printf("File set failed!\n");return NULL;}while (fscanf(fp, "%d%s%d", &tid, tname, &tscore) != EOF){p1 = (struct Person*)malloc(sizeof(struct Person));p1->next = NULL;p1->id = tid;strcpy(p1->name, tname);p1->score = tscore;if (i == 0){head = p1;p2 = p1;i = 1;}else{p2->next = p1;p2 = p1;}}return head;
}

查找

键盘输入学号,指针从链表开头开始寻找,当发现目标学号时输出并停止,如果搜索到结尾也未发现(指针最后为NULL),则输出未找到学号

void searchInfo()
{int tid;struct Person* p1 = head;printf("宁要查询的学生学号为?\n");scanf("%d", &tid);while (p1 != NULL){if (p1->id == tid){printf("学号\t姓名\t成绩\n");printf("%d\t%s\t%d\n", p1->id, p1->name, p1->score);break;}p1 = p1->next;}if (p1 == NULL)printf("未找到该学号!\n");
}

添加

申请一个新的内存,来保存新的学生信息,最后利用头插法来将信息链接到列表
如果学生学号重复了,则输出学号已存在并退出(毕竟学号只有一个,,)
如果刚刚手残输入的信息有误,可以选择撤销(人性化)

void addInfo()
{char tch;struct Person* node = (struct Person*)malloc(sizeof(struct Person));struct Person* tp = head;printf("输入添加学生的学号:");scanf("%d", &node->id);while (tp != NULL){if (tp->id == node->id){printf("该学号已存在\n");return;}tp = tp->next;}printf("输入添加学生的姓名:");scanf("%s", node->name);printf("输入添加学生的成绩:");scanf("%d", &node->score);getchar();printf("是否撤销刚刚的操作?(Y\\N)");tch = getchar();if (tch == 'Y'){printf("操作已撤销\n");return;}node->next = head;head = node;printf("添加成功\n");
}

添加列表

和添加函数一样,只不过可以连续添加很多学生信息

void addInfoList()
{char tch;int tid;char tname[20];int tscore;struct Person* tp = NULL;struct Person* p1 = head;printf("输入学生列表:\n输入学号为0表示输入结束\n");for (int i = 1;; i++){tp = (struct Person*)malloc(sizeof(struct Person));printf("输入第 %d 个学生的学号:", i);scanf("%d", &tid);if (tid == 0){free(tp);tp = NULL;printf("录入学生信息结束,共录入 %d 个学生信息\n", i - 1);return;}while (p1 != NULL){if (p1->id == tid){printf("该学号已存在\n");return;}p1 = p1->next;}printf("输入第 %d 个学生的姓名:", i);scanf("%s", tname);printf("输入第 %d 个学生的成绩:", i);scanf("%d", &tscore);tp->id = tid;strcpy(tp->name, tname);tp->score = tscore;tp->next = head;head = tp;}
}

修改

类似于查找函数,找到信息可以修改

void modifyInfo()
{int tid;struct Person* p1 = head;printf("输入修改的学生学号:");scanf("%d", &tid);while (p1 != NULL){if (p1->id == tid){printf("学生信息\n学号\t姓名\t成绩\n");printf("%d\t%s\t%d\n", p1->id, p1->name, p1->score);printf("修改姓名为:");scanf("%s", p1->name);printf("修改成绩为:");scanf("%d", &p1->score);printf("信息修改成功\n");break;}p1 = p1->next;}if (p1 == NULL)printf("未找到该学号\n");
}

链表有序归并(为链表排序函数做基础)

利用递归,,
递归式:当前链表 = 数值小的节点 指向 剩余的链表

struct Person* mergeIdList(struct Person* node1, struct Person* node2)
{if (node1 == NULL)return node2;if (node2 == NULL)return node1;if (node1->id < node2->id){node1->next = mergeIdList(node1->next, node2);return node1;}if (node1->id >= node2->id){node2->next = mergeIdList(node1, node2->next);return node2;}
}

链表排序

利用快指针和慢指针来找到链表的中间节点,然后,,分割链表
将两个链表继续递归分割,直到最小
将两个链表有序归并

struct Person* sortIdList(struct Person* node)
{struct Person* p1 = node;struct Person* p2 = node;struct Person* tp = node;struct Person* tp2 = NULL;struct Person* tp1 = NULL;if (node->next == NULL)return node;for (int i = 0; p1 != NULL && p1->next != NULL; i++){p1 = p1->next->next;p2 = p2->next;if (i != 0)tp = tp->next;}tp->next = NULL;tp2 = sortIdList(p2);tp1 = sortIdList(node);return mergeIdList(tp1, tp2);
}

输出

void displayList()
{struct Person* p1 = head;printf("学号\t姓名\t成绩\n");while (p1 != NULL){printf("%d\t%s\t%d\n", p1->id, p1->name, p1->score);p1 = p1->next;}
}

帮助菜单

输出帮助界面,用switch模块化处理数据,每次执行完之后返回1,每次执行退出时保存返回0

int help()
{char choice;printf("***************************************************************\n");printf("*                        学生管理系统                         *\n");printf("*输出成绩升序列表       输入:A                               *\n");printf("*输出学号升序列表       输入:B                               *\n");printf("*添加新的学生信息列表   输入:C                               *\n");printf("*添加新的学生信息       输入:D                               *\n");printf("*修改学生信息           输入:E                               *\n");printf("*查询学生信息           输入:F                               *\n");printf("*删除学生信息           输入:G                               *\n");printf("*退出菜单界面并保存     输入:H                               *\n");printf("*                                                             *\n");printf("*                                                             *\n");printf("***************************************************************\n");scanf("%c", &choice);system("CLS");switch (choice){case 'A':head = sortScoreList(head); displayList(); break;case 'B':head = sortIdList(head); displayList(); break;case 'C':addInfoList(); break;case 'D':addInfo(); break;case 'E':modifyInfo(); break;case 'F':searchInfo(); break;case 'G':deleteInfo(); break;case 'H':saveFile(); return 0;default:return 1;}return 1;
}

主函数

循环help(),help()返回0时退出

int main()
{head = loadFile();while (help()){system("pause");getchar();system("CLS");}return 0;
}

C语言基于链表的学生管理系统,超详细相关推荐

  1. C语言实现链表的基本操作(超详细注释)

    第一次学数据结构的时候,c语言基础实在太差,在尝试用c语言来实现的时候一直碰壁,数据结构书里的代码是伪代码,使用的时候各种内存访问冲突,各种锟斤拷烫烫烫,各种变量级别不同.于是我又重新学了一遍c语言, ...

  2. 用链表c语言程序设计,C语言程序设计-基于链表的学生成绩管理系统

    <C语言程序设计-基于链表的学生成绩管理系统>由会员分享,可在线阅读,更多相关<C语言程序设计-基于链表的学生成绩管理系统(18页珍藏版)>请在人人文库网上搜索. 1.华北科技 ...

  3. C语言链表学生成绩制作成链表,C语言程序设计课程设计基于链表的学生成绩管理系统.doc...

    C语言程序设计课程设计基于链表的学生成绩管理系统 华北科技学院计算机系综合性实验报告 PAGE 第 PAGE 10 页 华北科技学院计算机系综合性实验 实 验 报 告 课程名称 C语言程序设计 实验学 ...

  4. c语言程序设计 链表,c语言程序设计基于链表的学生成绩管理系统.doc

    c语言程序设计基于链表的学生成绩管理系统 华北科技学院计算机系综合性实验报告 PAGE 第 PAGE 10 页 华北科技学院计算机系综合性实验 实 验 报 告 课程名称 C语言程序设计 实验学期 20 ...

  5. java用链表做学生系统_C语言链表实现学生管理系统

    本文实例为大家分享了C语言链表实现学生管理系统的具体代码,供大家参考,具体内容如下 #include #include #include #include #include #include usin ...

  6. 基于Android的学生管理系统的设计与实现

    一.选题理论及实际意义 目前, 无线通信技术日臻成熟.在此背景下,移动通信技术快速发展,信息传递方式产生了革命性的变化,信息传递的质量.效率大大提高,为人们的生活提供了极大便利.随着WiFi及4G无线 ...

  7. 基于链表的票务管理系统

    这是一个基于链表的票务管理系统 实现功能(基于链表) 可手动输入各个线路地铁信息 可输出铁路所有信息 可根据用户输入线路信息查询线路详细信息 可根据输入起终信息查询票价 可查询列车时刻信息 可按起点/ ...

  8. 制作基于springboot的简易学生管理系统(详细)

    制作基于springboot的简易学生管理系统(详细) 基于书本与百度创作,内容简易,请多多指教( ̄▽ ̄)/ 设计一个简易学生管理系统 所需环境 创建一个springboot项目 设计数据库 配置Gr ...

  9. 基于ssm的学生管理系统

    基于ssm的学生管理系统 开发环境 开发软件 idea 也可以用eclipse导入 前端 lyaui 后端 spring springmvc mybatis 分页用的pagehelper maven管 ...

最新文章

  1. 二十一、挖掘模式评估方法
  2. 【Linux】一步一步学Linux——host命令(162)
  3. PythonOpenCV--Rtrees随机森林
  4. python安装多久_python安装与使用
  5. web网站服务(二)-1
  6. python输出实时时间
  7. url 编码(percentcode 百分号编码)
  8. STM32CubeMx之SD卡驱动
  9. TVS 瞬态抑制二极管指南
  10. 利用爬虫获得疫情信息,并存入表格
  11. NShape(开源矢量图形编辑器) 入门(二)
  12. shiro自定义filter,anon不生效
  13. 共轭相似以及共轭对角化
  14. persevere的用法_努力奋斗的英文短语 努力的英文意思是
  15. Arduino:设置ADC参考电压
  16. O2O模式为什么这么火
  17. 连接策略与搜索引擎优化
  18. 【操作系统】Linux内核和Windows系统的内核有什么区别?
  19. docker容器状态Exited(1)第一篇
  20. 微信app支付和微信网页支付 java

热门文章

  1. 王通:当下的SEO从业者该如何升级
  2. 【Tools】xshell5免费安装方法(亲测有效)
  3. 北京师范大学计算机学院院长,郭平-教授-北京师范大学系统科学学院
  4. 信息熵、条件熵、信息增益、相对熵 、交叉熵 解析
  5. Enscape室内设计商业化探索报告书
  6. 计算机系大学生适合的笔记本,推荐几款适合大学生笔记本 首选联想笔记本y系列...
  7. html影音播放器百度云,关于前端直播(videoJS与百度云web播放器:Cyberplayer3.0试用)...
  8. 构建完美作品集网站十步走
  9. webrtc的windows编译MDd或MD修改
  10. 要么忙着活,要么忙着死