#include任务#include #include using namespace std; struct score //定义存放学生信息的结点 { int num; //学号 string name; //姓名 string major; //专业 string classes; //班级 string sex; //性别 int age; //年龄 struct score* next; //next为指向下一结点的指针 }; struct score* head; //指向链表头结点的指针 struct score* head2; //指向链表头结点的指针 struct score* head3; //指向链表头结点的指针 int studentSum = 0; //学生总人数 class record { public: struct score* InsertRecord(struct score* h);//插入学生信息 struct score* DeleteRecord(struct score* h);//删除学生信息 struct score* AUpdateRecord(struct score* h, int x);//修改学生信息 void FindRecord(struct score* h, string x); //根据学生姓名查询学生信息 void FindRecord(struct score* h, int x); //根据学生学号查询学生信息 void MajorRecordFind(struct score* h, string x); //统计指定专业的学生人数,并显示全部指定专业学生信息 void ClasRecordFind(struct score* h, string x); //统计指定班级的学生人数,并显示全部指定班级学生信息 void AgeRecordFind(struct score* h, int x); //统计指定年龄的学生人数,并显示全部指定年龄学生信息 void SexRecordFind(struct score* h, string x); //统计指定性别的学生人数,并显示全部指定性别学生信息 void PrintRecord(struct score* h); //输出所有学生信息 void SaveRecordFile(struct score* h); //保存学生信息到文件 struct score* LoadRecordFile(struct score* h); //从文件中加载学生信息 }; score* Merge_List(score* list1, score* list2) { if (list1 == nullptr) return list2; if (list2 == nullptr) return list1; if (list1->num < list2->num) { list1->next = Merge_List(list1->next, list2); return list1; } else { list2->next = Merge_List(list1, list2->next); return list2; } return list1->num <= list2->num ? list1 : list2; } struct score* record::InsertRecord(struct score* h) { struct score* p1, * p2, * p3; p3 = new score; //创建新的学生结点 cout << "n请输入学生学号:"; cin >> p3->num; cout << "n请输入学生姓名:"; cin >> p3->name; cout << "n请输入学生的专业:"; cin >> p3->major; cout << "n请输入学生的班级:"; cin >> p3->classes; cout << "n请输入学生的性别:"; cin >> p3->sex; cout << "n请输入学生的年龄:"; cin >> p3->age; p3->next = NULL; //将要插入结点的指针域置为空 if (h == NULL) { h = p3; return h; } p1 = p2 = h; while (p1 != NULL && p3->num > p1->num) //查找结点的学号大于要插入结点的学号的第一个结点 { //指针p1表示符合条件的结点的指针,指针p2是指针p1的前一个结点的指针 p2 = p1; p1 = p1->next; } if (p1 == h) //插入位置为链表头结点前 { p3->next = h; h = p3; return h; } else //插入位置为链表的中间的链表的尾部 { p2->next = p3; p3->next = p1; } studentSum += 1; //学生人数加1 return h; //返回链表的头结点 } void record::PrintRecord(score* h) { if (h == NULL) { cout << "n抱歉,没有任何记录!"; return; } cout << "n学号 t姓名 t专业t班级t性别t年龄" << endl; while (h) //输出链表中每个结点的学生信息 { cout << h->num << "t" << h->name << "t" << h->major << "t" << h->classes << "t" << h->sex << "t" << h->age << endl; h = h->next; } } struct score* record::DeleteRecord(struct score* h) { struct score* p1, * p2; int num; if (h == NULL) //链表为空 { cout << "n抱歉,没有任何记录!"; return h; } p1 = p2 = h;//将链表的头指针赋给指针p1和p2 cout << "n请输入要删除记录的学生学号:"; cin >> num; while (p1 != NULL && p1->num != num)//查找结点的学号等于要删除学生学号的第一个结点 { //指针p1表示符合条件的结点的指针,指针p2是指针p1的前一个结点指针 p2 = p1; p1 = p1->next; } if (p1 == NULL) { cout << "n抱歉啊,表中没有该记录哦!"; return h; } if (p1->num == num) { studentSum -= 1;//学生人数减1 if (p1 == h) //删除的是头结点 h = h->next; else //删除的是非头结点 p2->next = p1->next; delete p1; //释放p1所指向的存储单元 } return h; } struct score* record::AUpdateRecord(struct score* h,int x)//修改学生信息 { struct score* p1; int num; if (h == NULL) { cout << "n抱歉,没有任何记录!"; return h; } p1 = h; cout << "n请输入要修改记录的学生学号:"; cin >> num; while (p1 != NULL && p1->num != num) //查找结点的学号等于要修改学生学号的结点指针 { p1 = p1->next; //将p1指针移到下一个结点 } if (p1 == NULL) //没有找到符合要求的结点 { cout << "n抱歉,表中没有该记录!"; return h; } if (p1->num == num) //找到符合要求的结点,并修改学生的相关信息 { if (x == 1) { cout << "n请重新输入学生的姓名:"; cin >> p1->name; } if (x == 2) { cout << "n请重新输入学生的专业:"; cin >> p1->major; } else if (x == 3) { cout << "n请重新输入学生的班级:"; cin >> p1->classes; } else if (x == 4) { cout << "n请重新输入学生的性别:"; cin >> p1->sex; } else if (x == 5) { cout << "n请重新输入学生的年龄:"; cin >> p1->age; } } return h; } void record::FindRecord(struct score* h, int num) //根据学生学号查找学生信息 { struct score* p1; if (h == NULL) { cout << "n抱歉,没有任何记录"; return; } p1 = h; //将链表的头结点指针h赋给指针p1 while (p1 != NULL && p1->num != num) //查找结点的学号等于要查找学生学号的结点指针 { p1 = p1->next; } if (p1 == NULL) //没有找到 { cout << "抱歉啊,表中没有该记录的哦!"; return; } if (p1->num == num) //找到并显示信息 { cout << "n学号 t姓名 t专业t班级t性别t年龄" << endl; cout << p1->num << "t" << p1->name << "t" << p1->major << "t" << p1->classes << "t" << p1->sex << "t" << p1->age << endl; } } void record::FindRecord(struct score* h, string name) //根据学生姓名查找学生信息 { struct score* p1; if (h == NULL) { cout << "n抱歉,没有任何记录!"; return; } p1 = h; while (p1 != NULL && p1->name != name) //查找结点的姓名等于要查找学生姓名的结点指针 { p1 = p1->next; } if (p1 == NULL) { cout << "n抱歉,表中没有该记录!"; return; } if (p1->name == name) { cout << "n学号 t姓名 t专业t班级t性别t年龄" << endl; cout << p1->num << "t" << p1->name << "t" << p1->major << "t" << p1->classes << "t" << p1->sex << "t" << p1->age << endl; } } void record::MajorRecordFind(struct score* h, string major)//按专业查询 { struct score* p = h; int count = 0; if (p == NULL) { cout << "n抱歉,没有任何记录!"; return; } while (p) { if (p->major == major) //查找结点的专业等于要查找学生专业的结点指针 { count += 1; } p = p->next; } cout << "该专业的人数为:"; cout << count << endl; cout << "改专业的学生信息为:" << endl; cout << "n学号 t姓名 t专业t班级t性别t年龄" << endl; p = h; while (p) { if (p->major == major) cout << p->num << "t" << p->name << "t" << p->major << "t" << p->classes << "t" << p->sex << "t" << p->age << endl; p = p->next; } } void record::ClasRecordFind(struct score* h, string classes)//按班级查询 { struct score* p = h; int count = 0; if (p == NULL) { cout << "n抱歉,没有任何记录!"; return; } while (p) { if (p->classes == classes) //查找结点的班级等于要查找学生班级的结点指针 { count += 1; } p = p->next; } cout << "该班级的人数为:"; cout << count << endl; cout << "该班级的学生信息为:" << endl; cout << "n学号 t姓名 t专业t班级t性别t年龄" << endl; p = h; while (p) { if (p->classes == classes) cout << p->num << "t" << p->name << "t" << p->major << "t" << p->classes << "t" << p->sex << "t" << p->age << endl; p = p->next; } } void record::SexRecordFind(struct score* h,string sex)//按性别查询 { struct score* p = h; int count = 0; if (p == NULL) { cout << "n抱歉,没有任何记录!"; return; } while (p) { if ( p->sex == sex) //查找结点的性别等于要查找学生性别的结点指针 { count += 1; } p = p->next; } cout << "该性别的人数为:"; cout << count << endl; cout << "该性别的学生信息为:" << endl; cout << "n学号 t姓名 t专业t班级t性别t年龄" << endl; p = h; while (p) { if (p->sex == sex) cout << p->num << "t" << p->name << "t" << p->major << "t" << p->classes << "t" << p->sex << "t" << p->age << endl; p = p->next; } } void record::AgeRecordFind(struct score* h, int age)//按年龄查询 { struct score* p = h; int count = 0; if (p == NULL) { cout << "n抱歉,没有任何记录!"; return; } while (p) { if (p->age == age) //查找结点的年龄等于要查找学生年龄的结点指针 { count += 1; } p = p->next; } cout << "该年龄的人数为:"; cout << count << endl; cout << "改年龄的学生信息为:" << endl; cout << "n学号 t姓名 t专业t班级t性别t年龄" << endl; p = h; while (p) { if (p->age == age) cout << p->num << "t" << p->name << "t" << p->major << "t" << p->classes << "t" << p->sex << "t" << p->age << endl; p = p->next; } } void record::SaveRecordFile(struct score* h) //将链表中的数据写入文件 { struct score* p; ofstream ofile; //定义输出文件对象 ofile.open("score.dat", ios::out); //以定的方式打开文件score.dat,若该文件不存在,则创建score.dat文件 if (!ofile) { cout << "n数据文件打开错误没有将数据写入文件!n"; return; } cout << "n学号 t姓名 t专业t班级t性别t年龄" << endl; while (h) { ofile << endl << h->num << "t" << h->name << "t" << "t" << h->major << "t" << h->classes << "t" << h->sex << "t" << h->age; p = h; //将当前结点的数据信息写入到文件中 h = h->next; delete p; } ofile.close(); } struct score* record::LoadRecordFile(struct score* h) { ifstream ifile; //定义输入文件对象 ifile.open("score.dat", ios::in);//以读写方式打开文件score.dat struct score* p; struct score* q = nullptr; if (!ifile) { cout << "n数据文件不存在,加载不成功!n"; return NULL; } char s[50]; ifile.getline(s, 50); //读取文件指针当前行数据 while (!ifile.eof()) { studentSum = studentSum + 1; p = new score; ifile >> p->num >> p->name >> p->major >> p->classes >> p->sex >> p->age; // p->next = NULL; if (h == NULL) { q = h = p; } else { q ->next = p; q = p; } } ifile.close(); return h; } void SystemMenu(record r) { int choice; while (1) { cout << "ntt欢迎进入学生信息管理系统!"; cout << "n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"; cout << "nt1、添加学生信息"; cout << "nt2、删除学生信息"; cout << "nt3、修改学生信息"; cout << "nt4、查询学生信息"; cout << "nt5、显示所有学生信息"; cout << "nt6、合并链表"; cout << "nt0、退出系统"; cout << "n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"; cout << "n请根据提示选择操作:"; cin >> choice; switch (choice) { case 1: //增加学生信息 while (1) { int c; cout << "n*************************************"; cout << "nt1、添加到主表(可存储)"; cout << "nt2、添加到副表(临时表不可存储)"; cout << "nt3、返回上级目录"; cout << "n*************************************"; cout << "n请根据提示选择操作:"; //显示查询子菜单 cin >> c; if (c ==1) { head = r.InsertRecord(head); } if (c == 2) { head2 = r.InsertRecord(head2); } if (c == 3) //退出查询子菜单 break; } break; case 2: //删除学生信息 head = r.DeleteRecord(head); break; case 3: //修改学生信息 while (1) { int c; cout << "n*************************************"; cout << "nt1、修改一项,姓名"; cout << "nt2、修改一项,专业"; cout << "nt3、修改一项,班级"; cout << "nt4、修改一项,性别"; cout << "nt5、修改一项,年龄"; cout << "nt6、返回上级目录"; cout << "n*************************************"; cout << "n请根据提示选择操作:"; //显示查询子菜单 cin >> c; if (c==1||c==2||c==3||c==4||c==5) //修改一项 { head = r.AUpdateRecord(head,c); } if (c == 6) //退出查询子菜单 break; } break; case 4: //查询学生信息 while (1) { int c; cout << "n*************************************"; cout << "nt1、根据学号查询学生信息"; cout << "nt2、根据姓名查询学生信息"; cout << "nt3、根据专业查询学生信息"; cout << "nt4、根据班级查询学生信息"; cout << "nt5、根据性别查询学生信息"; cout << "nt6、根据年龄查询学生信息"; cout << "nt7、返回上级目录"; cout << "n*************************************"; cout << "n请根据提示选择操作:"; //显示查询子菜单 cin >> c; if (c == 1) //根据学生学号查询学生信息 { int x; cout << "n请输入需要查询的学生学号:"; cin >> x; r.FindRecord(head, x); } if (c == 2) //根据学生姓名查询学生信息 { string name; cout << "n请输入需要查询的学生姓名:"; cin >> name; r.FindRecord(head, name); } if (c == 3) //根据专业查询学生信息 { string major; cout << "n请输入需要查询的学生专业:"; cin >> major; r.MajorRecordFind(head, major); } if (c == 4) //根据班级查询学生信息 { string classes; cout << "n请输入需要查询的学生班级:"; cin >> classes; r.ClasRecordFind(head, classes); } if (c == 5) //根据性别查询学生信息 { string sex; cout << "n请输入需要查询的学生性别:"; cin >> sex; r.SexRecordFind (head, sex); } if (c == 6) //根据年龄查询学生信息 { int age; cout << "n请输入需要查询的学生年龄:"; cin >> age; r.AgeRecordFind(head, age); } if (c == 7) //退出查询子菜单 break; } break; case 5: //输出所有学生成绩信息 while (1) { int c; cout << "n*************************************"; cout << "nt1、输出主表学生信息"; cout << "nt2、输出副表学生信息"; cout << "nt3、返回上级目录"; cout << "n*************************************"; cout << "n请根据提示选择操作:"; //显示查询子菜单 cin >> c; if (c == 1 ) { r.PrintRecord(head); } if (c == 2) { r.PrintRecord(head2); } if (c ==3) //退出查询子菜单 break; } break; case 6: // head3 = Merge_List(head, head2);//合并a,b break; } if (choice == 0)//退出系统 break; } } int main() { head = NULL; record r; //定义record类的对象r head = r.LoadRecordFile(head); //将文件中的数据读取到链表中 SystemMenu(r); //显示系统菜单,并处理用户选择 r.SaveRecordFile(head); //将链表中的数据写到文件中 return 0; }
采用链式存储完成学生信息的管理。学生信息包括:学号、姓名、专业、班级、性别、年龄等。要求实现学生信息数据的录入、插入、删除、查找、修改、排序、合并等。具体步骤包括:定义链表(任一种)的存储结构、实现相应基本操作、实现学生信息数据的管理;对链表中的学生信息按学号从小到大排序;将两个存储了学生信息的有序链表合并成一个链表。
说明1、定义学生结构体Student,
成员有:
学号(num【int】),姓名(name【string】),
专业(major【string】),班级(grade【string】),
性别(sex【string】),年龄(age【int】)。
定义链式存储结构体:
struct score* next; //next为指向下一结点的指针,struct score* head; //指向链表头结点的指针,struct score* head2; //指向链表头结点的指针,struct score* head3; //指向链表头结点的指针
2、由于涉及到的函数比较多,这里只对重点函数进行设计说明;
1)插入函数:先判断链表内是否有数据,如果没有,直接将头指针指向此数据,如果有数据,先进行比较大小,在合适的位置上插入数据。
2)删除函数:用P2保存要删除的元素的前一个元素,将p2的后继直接指向要删除元素的下一个元素。
3)合并两个链表,在系统中存在主表和副表,主表数据可以保存,副表不可以,合并链表时采用归并递归,将所有数据存储到主表内。
效果展示



