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