基于双向循环链表的学生管理系统

基于双向循环链表实现的学生管理系统,包括初始化,插入,删除,查抄,保存,自动按照姓名排序功能,退出并保存功能。

实现思想是将程序的各个部分划分为三个层次。主函数为界面层,即客户端层;其中后缀为Student的一般是某个功能的调度函数,属于逻辑层的内容;在调度函数之下有相应的被调度的函数,也就是相应功能的实现函数,一般后缀名为Node,意思就是这个函数直接操作链表中的结点,可以简单的划分为实现层;

这样分层实现呢有利于代码维护和个功能之间对包含或者重叠功能的直接调用,从而提高代码重用度,而降低代码冗余,并且最低成的实现函数也可以用于别的项目中对双向循环链表的操作。

本次学生管理系统的实现是先用一个初始化文件函数将一些学生信息先存入磁盘中,然后用初始化函数读出到链表中进行各种操作,保存功能和退出功能可以将链表中操作了的内容,也就是内存中的内容写入磁盘中,其中对文件的操作采用二进制读写文件,读写对象为学生结构体。

以下是代码实现:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #pragma warning (disable:4996)
  5
  6 //定义学生信息结点
  7 struct SNode{
  8     char name[50];
  9     char sex;
 10     int math;
 11     int chinese;
 12     int history;
 13 };
 14
 15 typedef struct SNode Student;
 16
 17 //定义链表结点
 18 struct Node{
 19     Student student;
 20     struct Node *left;
 21     struct Node *right;
 22 };
 23
 24 typedef struct Node Node;
 25
 26 void init(void);//初始化一个学生信息文件
 27 Node * createList();//创建双向循环链表
 28 void initializationList(Node *head);//初始化链表
 29 int insertStudent(Node *head);//菜单中插入功能调度函数
 30 int insertList(Node *head, Student newStudent);//插入功能实现函数,头插法插入结点
 31 void searchStudent(Node *head);//查找功能的调度函数
 32 Node *searchNode(Node *head, char *name);//查找功能的实现函数
 33 int  deleteStudent(Node *head);//菜单中删除功能的调度函数
 34 int deleteNode(Node *head, char *name);//删除功能的实现函数
 35 int lenList(Node *head);//求双向循环链表的长度
 36 void sortList(Node *head, int len);//依据姓名字符串的排序函数
 37 int saveToFile(Node *head);//将存放在内存中的学生数据写回磁盘文件中
 38 void printList(Node * head);//打印链表内容
 39
 40 int main(void)
 41 {
 42     //  init();//若没有学生信息文件,可打开此函数,初始化完成后可关闭此函数,
 43
 44     //可在本函数内修改初始学生信息
 45     printf("学生管理系统\n");
 46     printf("目前所有学生:\n");
 47
 48     Node *head = createList();//创建双向循环链表管理学生
 49     initializationList(head);//从文件中读取初始学生信息初始化链表
 50
 51     while (1)
 52     {
 53         int len = lenList(head);
 54         sortList(head, len);//输出之前按照名字排序
 55         system("CLS");//调用系统清屏函数
 56         printf("学生管理系统\n");
 57         printf("目前所有学生:\n");
 58         printList(head);//打印链表中的信息
 59         printf("1->添加\t2->删除\t3->查找4->保存5->退出\n");
 60         int select = 0;
 61         scanf("%d",&select);
 62         switch (select)
 63         {
 64         case 1:
 65             insertStudent(head);
 66             system("CLS");
 67             printf("学生管理系统\n");
 68             printf("目前所有学生:\n");
 69             printList(head);
 70             break;
 71         case 2:
 72             deleteStudent(head);
 73             system("CLS");
 74             printf("学生管理系统\n");
 75             printf("目前所有学生:\n");
 76             printList(head);
 77             break;
 78         case 3:
 79             searchStudent(head);
 80             printf("请按下任意键返回主菜单\n");
 81             getchar();
 82             break;
 83         case 4:
 84             saveToFile(head);
 85             printf("保存成功\n");
 86             system("CLS");
 87             printf("学生管理系统\n");
 88             printf("目前所有学生:\n");
 89             initializationList(head);
 90             printList(head);
 91             break;
 92         case 5:
 93             printf("程序即将退出\n");
 94             saveToFile(head);
 95             printf("保存成功\n");
 96             exit(1);
 97             break;
 98         }
 99     }
100     return 0;
101 }
102
103 //创建初始化文件
104 void init(void)
105 {
106     FILE *fop = fopen("D:/Test/classTest/student.txt", "wb");
107     Student students[5] = { { "zhao", ‘m‘, 90, 100, 100 },
108     { "qian", ‘w‘, 60, 60, 60 },
109     { "sun", ‘m‘, 85, 85, 90 },
110     { "li", ‘m‘, 60, 100, 100 },
111     { "zhou", ‘w‘, 100, 100, 100 } };
112     fwrite(students, sizeof(Student), 5, fop);
113     fclose(fop);
114 }
115
116 //创建双向循环链表
117 Node * createList()
118 {
119     Node *head = (Node *)malloc(sizeof(Node));
120     if (head)
121     {
122         head->left = head;
123         head->right = head;
124         return head;
125     }
126     else
127         return NULL;
128 }
129
130 //初始化链表
131 void initializationList(Node *head)
132 {
133     FILE *fip = fopen("D:/Test/classTest/student.txt", "rb");
134     Student newStudent;
135     while (fread(&newStudent, sizeof(Student), 1, fip) != 0){
136         insertList(head, newStudent);
137     }
138 }
139
140 //菜单中插入功能调度函数
141 int insertStudent(Node *head)
142
143 {
144     Student newStudent;
145     printf("请输入学生信息:\n");
146     printf("姓名:");
147     scanf("%s",&newStudent.name);
148     getchar();
149     printf("性别:");
150     newStudent.sex=getchar();
151     printf("数学:");
152     scanf("%d",&newStudent.math);
153     printf("语文:");
154     scanf("%d",&newStudent.chinese);
155     printf("历史:");
156     scanf("%d",&newStudent.history);
157     insertList(head, newStudent);
158 }
159
160 //结点插入
161 //插入功能实现函数,头插法插入
162 int insertList(Node *head, Student data)
163 {
164     Node *newNode = (Node *)malloc(sizeof(Node));
165     if (newNode)
166     {
167         newNode->student = data;
168         newNode->left = head;
169         newNode->right = head->right;
170         head->right = newNode;
171         newNode->right->left = newNode;
172         return 1;
173     }
174     else
175         return -1;
176 }
177
178 //菜单中删除功能的调度函数
179 int  deleteStudent(Node *head)
180 {
181     printf("请输入需要删除的学生的姓名:");
182     char name[50];
183     scanf("%s",name);
184     getchar();
185     int flag=deleteNode(head, name);
186     if (flag)
187         printf("删除成功\n");
188     else
189         printf("删除失败\n");
190     return flag;
191 }
192
193 //删除功能的实现函数
194 int deleteNode(Node *head, char *name)
195 {
196     Node *searchStudent = searchNode(head, name);
197     if (searchStudent){
198         searchStudent->left->right = searchStudent->right;
199         searchStudent->right->left = searchStudent->left;
200         free(searchStudent);
201         return 1;
202     }
203     return 0;
204 }
205
206 //查找功能的调度函数
207 void searchStudent(Node *head)
208 {
209     printf("请输入需要删除的学生的姓名:");
210     char name[50];
211     scanf("%s", name);
212     getchar();
213     Node *result = searchNode(head, name);
214
215     if (result)
216     {
217         printf("姓名\t性别\t数学\t语文\t历史\n");
218         printf("%s\t%c\t%d\t%d\t%d\n", result->student.name, result->student.sex,
219             result ->student.math, result->student.chinese, result->student.history);
220     }
221     else
222         printf("没有找到该学生\n");
223 }
224
225 //查找功能的实现函数
226 Node *searchNode(Node *head, char *name)
227 {
228     Node *left = head;
229     Node *right = head;
230     do
231     {
232         left = left->left;
233         right = right->right;
234         if (strcmp(left->student.name, name)==0)
235             return left;
236         if (strcmp(right->student.name, name)==0)
237             return right;
238
239     } while (left != right && left->left != right);
240     return NULL;
241 }
242
243 //依据姓名字符串的排序函数
244 void sortList(Node *head, int len)
245 {
246     Node *p, *q, *max, *temp;
247     Student t;
248     p = head->right;
249     q = p->right;
250     int i = 0, j = 0;
251     for (i = 0; i < len - 1; i++)
252     {
253         if (p == head)
254             break;
255         max = p;
256         q = p;
257         for (j = i; j < len; j++)
258         {
259             if (q == head)
260                 break;
261             if (strcmp(max->student.name, q->student.name)>0)
262                 max = q;
263             q = q->right;
264         }
265         if (max != p)
266         {
267             t = max->student;
268             max->student = p->student;
269             p->student = t;
270         }
271         p = p->right;
272     }
273 }
274
275 //求双向循环链表的长度
276 int lenList(Node *head)
277 {
278     Node *p = head;
279     int len = 0;
280     while (p->right != head){
281         len++;
282         p = p->right;
283     }
284     return len;
285 }
286
287 //打印链表内容
288 void printList(Node * head)
289 {
290     Node *p = head->right;
291     while (p != head)
292     {
293         printf("%s\t%c\t%d\t%d\t%d\n", p->student.name, p->student.sex,
294         p->student.math, p->student.chinese, p->student.history);
295         p = p->right;
296     }
297 }
298
299 //将存放在内存中的学生数据写回磁盘文件中
300 int saveToFile(Node *head)
301 {
302     FILE *fop = fopen("D:/Test/classTest/student.txt", "wb");
303
304     Node *p = head->right;
305     while (p != head)
306     {
307         fwrite(&p->student,sizeof(Student), 1, fop);
308         p = p->right;
309     }
310     return 1;
311 }
312  
时间: 2024-10-19 15:15:25

基于双向循环链表的学生管理系统的相关文章

学生管理系统——基于双向循环链表

基于双向循环链表实现的学生管理系统,包括初始化,插入,删除,查抄,保存,自动按照姓名排序功能,退出并保存功能. 实现思想是将程序的各个部分划分为三个层次.主函数为界面层,即客户端层:其中后缀为Student的一般是某个功能的调度函数,属于逻辑层的内容:在调度函数之下有相应的被调度的函数,也就是相应功能的实现函数,一般后缀名为Node,意思就是这个函数直接操作链表中的结点,可以简单的划分为实现层: 这样分层实现呢有利于代码维护和个功能之间对包含或者重叠功能的直接调用,从而提高代码重用度,而降低代码

基于SSH框架的学生公寓管理系统的质量属性

系统名称:学生公寓管理系统 首先介绍一下学生公寓管理系统,在学生公寓管理方面,针对学生有关住宿信息问题进行管理,学生公寓管理系统主要包含了1)学生信息记录:包括学号.姓名.性别.院系.班级:2)住宿信息记录:包括宿舍楼号.宿舍号.电费信息.维修记录:3)报修信息记录:包括宿舍楼号.宿舍号.报修品.时间.维修状态:4)后勤人员记录:包括工号.姓名.联系方式:5)电费信息记录:包括宿舍楼号.宿舍号.电剩余量.使用量.缴费金额.剩余金额:6)学生晚归记录:晚归学生的学号.姓名.时间.宿舍号.日期.和原

学生管理系统(用中间件)-------基于FORM组件

x学生管理系统(用中间件)-------基于FORM组件 目的:实现学生,老师,课程的增删改查 models.py from django.db import models # Create your models here. class UserInfo(models.Model): """ 用户表:既有班主任也有老师 """ username = models.CharField(max_length=32) password = model

jsp学习之基于mvc学生管理系统的编写

mvc开发模式:分别是 model层 view层 Control层 在学生管理系统中,model层有学生实体类,数据访问的dao层,view层主要是用于显示信息的界面,Control层主要是servlet处理用户请求 在学生管理系统中,我的分包如下 cn.entity包下有学生的实体类,该类有学生的各种属性 cn.dao包是数据访问层,里面写了一个studeDao的接口该接口里面有抽象方法分别是增删该查 cn.dao.impl包中是studenDao的实现类 cn.service业务逻辑层在se

基于struts2框架开发的学生管理系统

学生管理系统采用struts2框架作为后台开发框架,jsp实现页面数据的展示,数据库采用mysql.功能介绍:包含学生信息管理,班级信息管理,年级信息管理,系统信息管理等功能.数据库模型设置如下:CREATE TABLE t_class (classId int(11) NOT NULL auto_increment,className varchar(20) default NULL,gradeId int(11) default NULL,classDesc text,PRIMARY KEY

第33课 双向循环链表的实现

1. DTLib中双向链表的设计思路 (1)数据结点之间在逻辑上构成双向循环,这有别于Linux内核链表的实现. (2)头结点仅用于结点的定位,而Linux内核链表是将头结点作为循环的一部分. 2. 实现思路 (1)通过模板定义DualCircleList类,继承自DualLinkList类 (2)在DualCircleList内部使用Linux内核链表进行实现(另类实现) (3)使用struct list_head定义DualCircleList的头结点 (4)特殊处理:循环遍历时忽略头结点

准备用C51做个学生管理系统(1)

为了做这个看起来很容易,做起来很麻烦的基于51的学生管理系统,我得准备很多的知识,首先是51单片机的一些IO.定时器差不多就可以了,硬件方面还要有数码管.LCD1602.矩阵键盘等知识,至于代码就需要数据结构双向链表的知识就差不多了,用到的软件无非也就是protues.keil.protel这三剑客了. 1.为什么要用到数码管呢,因为很少做这些硬件的东西,用数码管主要是为了验证我的矩阵键盘功能有没有用罢了,数码管的abcdefg对应那几根“杠杠”的亮否可以直接显示亮的数据,因为矩阵键盘是8X8的

C语言通用双向循环链表操作函数集

说明 相比Linux内核链表宿主结构可有多个链表结构的优点,本函数集侧重封装性和易用性,而灵活性和效率有所降低.     可基于该函数集方便地构造栈或队列集.     本函数集暂未考虑并发保护. 一  概念 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序通过链表中的指针链接次序实现.链表由一系列存储结点组成,结点可在运行时动态生成.每个结点均由两部分组成,即存储数据元素的数据域和存储相邻结点地址的指针域.当进行插入或删除操作时,链表只需修改相关结点的指针域即可,因此相比线性

控制台的学生管理系统---结对编程

需求分析: 学生管理系统定义: 基于控制台的学生管理系统,对基本的学生信息通过控制台打印输出进行管理 学生管理系统: 功能: 进行学生的基本注册. 进行学生登陆. 对学生的基本信息进行查询. 结对编程概述: 定义: 结对编程技术是指两位程序员坐在同一工作台前开发软件.与两位程序员各自独立工作相比,结对编程能编写出质量更高的代码. 概述: 结对编程技术是一个非常简单和直观的概念,能达到事半功倍的工作效果.但是,人与人之间的合作不是一件简单的事情——尤其当人们都早已习惯了独自工作的时候.实施结对编程