最近,在准备找工作,看到了单链表这里,就自己试着用单链表编写了一个学生信息管理系统。自己水平不高,很简单的一个小系统,贴出来请大家帮我指出错误,请大家指教!谢谢!
// 学生信息系统.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> #include <conio.h> using namespace std; #define LEN sizeof(struct student_list)//结构体的长度 struct student_list { int num;//学号 double score;//分数 struct student_list* next;//指向下一节点的指针 }; /********************************************学生信息系统*********************************************************** ***名称:学生信息系统 ***功能:1.录入学生信息 2.增添学生信息 3.删除学生信息 4.查找学生信息 5.排列学生信息 6.修改学生信息 7.安全退出系统 ***所使用的函数及作用: int GetKey():读取按键的值,判断选择了哪一项功能 void ShowMenu():介绍学生信息系统的功能及对应的按键 int print_list(struct student_list* list_head):打印学生的信息 struct student_list* create_list():录入学生信息 struct student_list* insert_list_node(struct student_list* list_head, struct student_list* list_student):增添学生的信息 struct student_list* delete_list_node(struct student_list* list_head, int position):删除学生的信息 struct student_list* sort_list(struct student_list* list_head):冒泡法排列学生信息(按照学号从小到大排列) struct student_list* find_node(student_list* list_head, int stu_num):查找节点信息根据学号 int find_stu_node(student_list* list_head, int stu_num):查找修改的学生是否在链表中已经存在 struct student_list* modify_node(student_list* list_head, int num_old, int num_new, int socre_new):修改学生信息 ************************************************************************************************************************/ /************************************ ***功能:读取按键,判断选择了哪一项功能 ***返回:void ************************************/ int GetKey() { int press_key; press_key = getch();//功能键需要读两次值 return press_key; } /********************************* ***函数名称:ShowMenu ***函数说明:介绍学生信息系统的功能及对应的按键 ***函数返回:void *********************************/ void ShowMenu() { cout<<" 学 生 成 绩 管 理 系 统 "<<endl; cout<<" 1.录入学生信息 "<<endl; cout<<" 2.增添学生信息 "<<endl; cout<<" 3.删除学生信息 "<<endl; cout<<" 4.查找学生信息 "<<endl; cout<<" 5.排列学生成绩 "<<endl; cout<<" 6.修改学生信息 "<<endl; cout<<" 7.安全退出系统 "<<endl; cout<<"请选择:"; } /********************************* ***功能:创建n个节点的链表 ***返回:指向链表表头的指针 *********************************/ struct student_list* creat_list() { cout << " 欢迎使用万花筒学生信息系统! " << endl; cout << " 请输入学生的学号和成绩...... " << endl; cout << "温馨提示:" << endl; cout << " 当输入学号小于0时,表示学生信息录入完毕! " << endl; struct student_list* list_head = NULL;//链表的头 struct student_list* list_temp0 = NULL; struct student_list* list_temp1 = NULL; int n = 0;//先创建个空链表,静态变量保存在读写数据段,在开始的时候就赋值,并且具有“记忆性” do { list_temp0 = (struct student_list*)malloc(LEN);//开辟空间 cout << "输入学号:"; cin >> list_temp0->num; if (list_temp0->num <= 0) { cout << "输入信息完毕!" << endl; break; } cout << "输入分数:"; cin >> list_temp0->score; /*************插表头******************/ //list_temp0->next = list_head; //list_head = list_temp0;
/**************链表尾****************/ ++n; if (1 == n) { list_head = list_temp0; list_temp0->next = NULL; } else { list_temp1->next = list_temp0; list_temp0->next = NULL; } list_temp1 = list_temp0;//保存,产生新节点时候会用 }while (list_temp0->num != 0); free(list_temp0); list_temp0 = NULL; return list_head;//退出的时候要返回一个值,否则不能打印,返回值的位置要写对 } /********************************* ***功能:打印链表 ***返回:成功返回0,失败返回1 *********************************/ void print_list(struct student_list* list_head) { struct student_list* p; p = list_head; if (p == NULL) cout << "这是一个空链表!请创建或打印一个非空列表!" << endl; else { do { cout << "节点的地址:0x" << p << "->学号:" << p->num << "->分数:" << p->score << endl; p = p->next; } while (p != NULL); } } /***************************************************** ***功能:将一个节点插入到大于链表中学号的后面,链表中的学号 要求从小到大排列 ***返回:指向链表表头的指针 ****************************************************/ struct student_list* insert_list_node(struct student_list* list_head, struct student_list* list_student) { struct student_list* p0;//p0用来指向头结点 struct student_list* p1;//p1用来指向要插入的节点 struct student_list* p2; p0 = list_head; p1 = list_student; if (list_head == NULL)//若链表为空 { list_head = p1; p1->next = NULL; } else//若链表不为空 { //从头节点开始比较,直到插入学号大于于当前节点,或当前节点指向链表尾 while (p1->num > p0->num && p0->next != NULL) { p2 = p0;//备份 p0 = p0->next;//向后移一位 } //若当前节点指向链表尾还没有找到插入位置 if (p0->next == NULL) { if (list_head == p0)//若当前节点只有一个并且是头节点 { if (p0->num < p1->num) { p1->next = p0->next; p0->next = p1; } else { list_head = p1; p1->next = p0; } } else//若当前节点不是头节点 { if (p1->num < p0->num)//若插入的学号小于最后一个节点的学号 { p1->next = p2->next; p2->next = p1; } else//若插入的学号大于最后一个节点的学号 { p1->next = p0->next; p0->next = p1; } } } //或者若是插入节点的学号比当前节点的学号小 else if (p1->num < p0->num) { if (list_head == p0)//若当前节点是头节点 { list_head = p1; p1->next = p0; } else//若当前节点不是头节点 { if (p0->next != NULL)//若当前节点不指向链表结尾 { p1->next = p2->next; p2->next = p1; } else//若当前节点指向链表结尾 { p1->next = p0->next; p0->next = p1; } } } } return list_head; } /*************************** ***功能:删除指定位置的节点 ***返回:指向链表表头的指针 ***************************/ struct student_list* delete_list_node(struct student_list* list_head, int position) { struct student_list* p0; struct student_list* p1; p0 = list_head;//p0是移动节点,p0初始指向头节点 if (list_head == NULL)//如果是空链表 { cout << "这是一个空链表!" << endl; } else { while (p0->num != position && p0->next != NULL)//若当前节点的学号不是指定删除的学号,并且没指向链表的结尾 { p1 = p0; p0 = p0->next; } if (p0->num == position) { if (list_head == p0)//若当前节点是头节点 { p0 = p0->next;//p0指向下一节点 list_head = p0;//下一节点作为头节点 } else p1->next = p0->next;//把当前节点指向的下一节点地址给前一节点 } else if (p0->next == NULL) { if (p0->num == position)//在最后找到删除的节点 p1->next = p0->next;
else//若是没有找到要删除的节点 cout << "该节点在链表中不存在,请另外选择节点!" << endl; } } return list_head; } /*************************** ***功能:按照学生的学号排列节点 ***返回:指向链表表头的指针 ***************************/ struct student_list* sort_list(struct student_list* list_head) { struct student_list* endpt;//每趟排序的末尾节点 struct student_list* p;//中间变量 struct student_list* p1; struct student_list* p2; if (list_head == NULL) { cout << "这是一个空链表!" << endl; } else { p1 = (struct student_list*)malloc(LEN);//开辟一个链表空间 p1->next = list_head; list_head = p1; for (endpt = NULL; endpt != list_head; endpt = p) { for (p = p1 = list_head; p1->next->next != NULL; p1 = p1->next) { if (p1->next->num > p1->next->next->num)//若前一节点的学号大于后一节点的学号 { p2 = p1->next->next;//把后一节点给临时节点 p1->next->next = p2->next;//将前一节点指向后一节点所指向的节点 p2->next = p1->next;//让后一节点指向前一节点 p1->next = p2;//让p1指向后一节点 p = p1->next->next;//p往链表的头移动一位 } } } p1 = list_head;//p1指向链表的头 list_head = list_head->next;//将p1的下一节点作为链表头 free(p1); p1 = NULL; } return list_head; } /*************************** ***功能:根据学生的学号查找学生 ***返回:指向链表表头的指针 ***************************/ struct student_list* find_node(student_list* list_head, int stu_num) { struct student_list* p; p = list_head; if (list_head == NULL) cout << "这是一个空链表!" << endl; else { while (p != NULL && p->num != stu_num) p = p->next;
if (p != NULL && p->num == stu_num) cout << "节点的地址:0x" << p << "->学号:" << p->num << "->分数:" << p->score << endl;
if (p == NULL) { cout << " " << endl; cout << " 很抱歉,您要查找的学生信息不存在!" << endl; } } return list_head; } /*************************** ***功能:根据学生的学号查找学生 ***返回:找到返回1,没找到返回0 ***************************/ bool find_stu_node(student_list* list_head, int stu_num) { struct student_list* p; p = list_head; bool find_flag = false; if (list_head == NULL) cout << "这是一个空链表!" << endl; else { while (p != NULL && p->num != stu_num) p = p->next; if (p != NULL && p->num == stu_num) find_flag = true; if (p == NULL) find_flag = false; } return find_flag; } /********************************** ***功能:输入想修改学生的学号,并修改 ***返回:指向链表表头的指针 **********************************/ struct student_list* stu_new; struct student_list* modify_node(student_list* list_head, int num_old, int num_new, int socre_new) { struct student_list* p; p = list_head; if (list_head == NULL) cout << "这是一个空链表!" << endl; else { stu_new = (struct student_list*)malloc(LEN);//将需要修改的信息作为一个节点 stu_new->num = num_new; stu_new->score = socre_new; if (find_stu_node(list_head, num_old)) { if (num_old == num_new)//若是不修改学号,只修改成绩 { while (p != NULL && p->num != num_old) p = p->next; if (p->num == num_old) p->score = socre_new; } else//修改学号,也修改成绩 { delete_list_node(list_head, num_old); insert_list_node(list_head, stu_new); } } else { cout << " " << endl; cout << " 您要修改的学生信息不存在! " << endl; cout << " 您要添加该学生的信息请输入9,继续请输入任意数字! " << endl; cout << "请输入:"; int key_9; cin >> key_9; if (9 == key_9) insert_list_node(list_head, stu_new); } } return list_head; } int main() { int key_value; int stu_num; int stu_num_new; int stu_score; static struct student_list *student = NULL; struct student_list* stu = NULL; ShowMenu(); while (1) { key_value = GetKey(); switch (key_value) { case '1': cout << "1.录入学生信息" << endl; cout << " " << endl; student = creat_list(); print_list(student); cout << " " << endl; cout << " 继续操作请输入1-6,退出请输入7! " << endl; break; case '2': cout << "2.增添学生信息" << endl; cout << " " << endl; stu = (struct student_list*)malloc(LEN); cout << "学号:"; cin >> stu->num; cout << "分数:"; cin >> stu->score; student = insert_list_node(student, stu); print_list(student); cout << " " << endl; cout << " 继续操作请输入1-6,退出请输入7! " << endl; break; case '3': cout << "3.删除学生信息" << endl; cout << " " << endl; int student_num; cout << "请输入要删除的学号:"; cin >> student_num; student = delete_list_node(student, student_num); cout << " " << endl; cout << " 您是否想查看现在的学生信息? " << endl; cout << " " << endl; cout << " 查看学生信息请输入8,跳过请输入任意数字! " << endl; cout << "请输入:"; int key_delete; cin >> key_delete; if (8 == key_delete) print_list(student); cout << " " << endl; cout << " 继续操作请输入1-6,退出请输入7! " << endl; break; case '4': cout << "4.查找学生信息" << endl; cout << " " << endl; cout << "请输入您想要找的学生的学号:"; cin >> stu_num; student = find_node(student, stu_num); cout << " " << endl; cout << " 继续操作请输入1-6,退出请输入7! " << endl; break; case '5': cout << "5.排列学生信息" << endl; cout << " " << endl; student = sort_list(student); if (student != NULL)//若是空链表就不用再显示出来 print_list(student); cout << " " << endl; cout << " 继续操作请输入1-6,退出请输入7! " << endl; break; case '6': cout << "6.修改学生信息" << endl; cout << " " << endl; cout << "请输入您要修改的学生的学号:"; cin >> stu_num; cout << "请输入您修改后的学生的信息:"; cin >> stu_num_new >> stu_score; student = modify_node(student, stu_num, stu_num_new, stu_score); print_list(student); cout << " " << endl; cout << " 继续操作请输入1-6,退出请输入7! " << endl; break; case '7': cout << "7.安全退出系统" << endl; cout << " " << endl; cout << " 感谢您使用本系统,欢迎再次使用! " << endl; free(student); free(stu_new);//find_stu_node函数开辟的空间,在子函数中不能释放,把它定义为全局变量,在退出系统的时候释放 student = NULL; stu_new = NULL;
system("pause");
return 0; default: cout << "您输入的数字不在1-7的范围内!继续操作请输入1-6,退出请输入7!" << endl; cout << " " << endl; cout << "请选择:"; break; } } }
该系统的运行界面如下图所示:
写这个小系统主要是为了学习单链表,我水平不高,做的不好,希望大家多多指教,谢谢!关于链表的知识,请您自己查找相关资料阅读。