赞
踩
题目:宿舍管理系统(为宿舍管理人员编写一个宿舍管理查询软件)
要求:
1.采用交互工作方式
2.建立数据文件,数据文件按关键字(姓名、学号、房号)进行排序(冒泡、选择、插入排序等任选一种)
3.查询菜单:用二分查找实现以下操作,并输出查询结果(可以连续操作)
A.按姓名查询
B.按学号查询
C.按房号查询
代码:
list.cpp
#include<iostream> #include<string.h> using namespace std; struct Node { //定义结构体,存放学生信息 string sname; int sid; int sroom; Node *next; Node(); //构造函数 }; Node::Node() { sid = 0; sname = '\0'; sroom = 0; next = NULL; } class List { public: List(); //构造函数 int size() const; //返回线性表的大小 Node *set_position(int position) const; //让指针指向指定位置 void insert(const Node &x);//插入数据 void sid_sort(); //按学号排序 void sname_sort(); //按姓名排序 void sroom_sort(); //按房号排序 void sidbinary_search(int target); //按学号查找 void snamebinary_search(string target); //按名字查找 void sroombinary_search(int target); //按宿舍号查找 void print(); ~List(); //析构函数 protected: int count; //计数器 Node *head; //头指针 }; List::List() //构造函数 { count = 0; //计数器置0 head = NULL; } int List::size() const //返回线性表大小 { return count; } Node *List::set_position(int position) const //让指针指到指定位置 { Node *q = head; for (int i = 0; i < position; i++) q = q->next; //遍历,找到指定位置 return q; } void List::insert(const Node &x)//插入数据 { Node *p = new Node(); p->sid = x.sid; p->sname = x.sname; p->sroom = x.sroom; p->next = NULL; if(count == 0)//如果原链表没有数据则插入的是表头 { head = p; } else { Node *q = head; while(q->next != NULL) { q = q->next; } q->next = p; } count++; cout << "Success!" << endl; } void List::sid_sort()//按学号排序 { if(count == 0) { cout << "No Student Information!" << endl; return ; } Node *first_unsorted;//指向无序结点 Node *position; //指向可以插入结点位置 Node *inter; //找到的可以插入的结点 Node *current;//用来指向有序链表的结点 first_unsorted = head->next;//开始无序结点是current的下一个结点 current = head; current->next = NULL; while(first_unsorted)//直到链表最后一个结点结束 { inter = first_unsorted;//每次从一个新的无序结点开始 first_unsorted = first_unsorted ->next;//指向下一个无序结点 current = head; //而有序结点则从第一个开始,每次从最小的开始比较;如果比当前最小的还小放在它前面 while(current && (current->sid < inter->sid))//如果比当前有序结点大,则和下一个有序结点比较 { position = current; current = current->next; } if(current == head )//即比第一个有序结点还小,则头插 head = inter; else //要插入的不是头结点则把它插入找出的合适的位置 position->next = inter; inter->next = current;//将新结点与后面的链表连接起来 } cout << "Sort Success!" << endl; } void List::sname_sort()//按姓名排序 { if(count == 0) { cout << "No Student Information!" << endl; return ; } Node *first_unsorted;//指向无序结点 Node *position; //指向可以插入结点位置 Node *inter; //找到的可以插入的结点 Node *current;//用来指向有序链表的结点 current = head;//开始认为第一个结点有序 first_unsorted = head->next;//开始无序结点是current的下一个结点 current->next = NULL; while(first_unsorted)//直到链表最后一个结点结束 { inter = first_unsorted;//每次从一个新的无序结点开始 first_unsorted = first_unsorted ->next ;//指向下一个无序结点 current = head ; //而有序结点则从第一个开始,每次从最小的开始比较;如果比当前最小的还小放在它前面 while(current && (current->sname < inter->sname))//如果比当前有序结点大,则和下一个有序结点比较 { position = current; current = current->next ; } if(current == head )//即比第一个有序结点还小,则头插 head = inter; else //要插入的不是头结点则把它插入找出的合适的位置 position->next = inter; inter->next = current;//将新结点与后面的链表连接起来 } cout << "Sort Success!" << endl; } void List::sroom_sort()//按房号排序 { if(count == 0) { cout << "No Student Information!" << endl; return ; } Node *first_unsorted;//指向无序结点 Node *position; //指向可以插入结点位置 Node *inter; //找到的可以插入的结点 Node *current;//用来指向有序链表的结点 current = head;//开始认为第一个结点有序 first_unsorted = head->next;//开始无序结点是current的下一个结点 current->next = NULL; while(first_unsorted)//直到链表最后一个结点结束 { inter = first_unsorted;//每次从一个新的无序结点开始 first_unsorted = first_unsorted ->next;//指向下一个无序结点 current = head ; //而有序结点则从第一个开始,每次从最小的开始比较;如果比当前最小的还小放在它前面 while(current && (current->sroom < inter->sroom))//如果比当前有序结点大,则和下一个有序结点比较 { position = current; current = current->next ; } if(current == head )//即比第一个有序结点还小,则头插 head = inter; else //要插入的不是头结点则把它插入找出的合适的位置 position->next = inter; inter->next = current;//将新结点与后面的链表连接起来 } cout << "Sort Success!" << endl; } void List::print() //按顺序打印出线性表数据 { Node *p = head; cout << "sid sname sroom" << endl; while(p != NULL) { cout << p->sid << " " << p->sname << " " << p->sroom << endl; p = p->next; } } void List::sidbinary_search(int target) //按学号查找 { Node *mid; int frontnum = 0; int lastnum = count - 1;//前后下标,用来规定范围 while (frontnum < lastnum) //当前下标小于后下标,继续循环 { int midnum = (frontnum + lastnum) / 2;//找出中间坐标 mid = set_position(midnum); if(mid->sid < target) frontnum = midnum + 1; //如果中间的值小于要查找的值,说明要查找的值在后半部分,前下标移到中间位置的后一个位置 else lastnum = midnum; //如果中间的值大于要查找的值,说明要查找的值在前半部分,后下标移到中间位置 } if (lastnum < frontnum) { cout << "Student information is not exit!" << endl; //当前下标大于后下标时,说明没有找到 } else //当前后下标指向同一个元素 { mid = set_position(frontnum); if (mid->sid == target) //判断这个结点中的数据与所查找的数据是否一致,如果一致则输出,该位置一定是在这个线性表中第一次出现的位置 { cout << "sid" << " "<< "sname" << " "<< "sroom" << endl; cout << mid->sid << " " << mid->sname << " " << mid->sroom << endl; } else //如果不是则说明表中没有这个数据 { cout << "Student information is not exit!" << endl; } } } void List::snamebinary_search(string target) //按姓名查找 { Node *mid; int frontnum = 0; int lastnum = count - 1;//前后下标,用来规定范围 while (frontnum < lastnum) //当前下标小于后下标,继续循环 { int midnum = (frontnum + lastnum) / 2;//找出中间坐标 mid = set_position(midnum); if (mid->sname < target) frontnum = midnum + 1; //如果中间的值小于要查找的值,说明要查找的值在后半部分,前下标移到中间位置的后一个位置 else//当前后下标指向同一个元素 lastnum = midnum; //如果中间的值大于要查找的值,说明要查找的值在前半部分,后下标移到中间位置 } if (lastnum < frontnum) //当前下标大于后下标时,说明没有找到 { cout << "Student information is not exit!" << endl; } else { //当前后下标指向同一个元素 mid = set_position(frontnum); if (mid->sname == target)//判断这个结点中的数据与所查找的数据是否一致,如果一致则输出,该位置一定是在这个线性表中第一次出现的位置 { cout << "sname" << " "<< "sid" << " "<< "sroom" << endl; cout << mid->sname << " " << mid->sid << " " << mid->sroom << endl; if(mid->next != NULL) { Node *p = mid->next; while(p && (p->sname == mid->sname)) //查找后面还有没有相同的数据 { cout << p->sname << " " << p->sid << " " << p->sroom << endl; p = p->next; } //如果这个位置的值等于要查找的值,则该位置一定是在这个表中第一次出现的位置 } } else//如果不是则说明表中没有这个数据 { cout << "Student information is not exit!" << endl; } } } void List::sroombinary_search(int target) //按房号查找 { Node *mid; int frontnum = 0; int lastnum = count - 1;//前后下标,用来规定范围 while (frontnum < lastnum) //当前下标小于后下标,继续循环 { int midnum = (frontnum + lastnum) / 2;//找出中间坐标 mid = set_position(midnum); if (mid->sroom < target) frontnum = midnum + 1; //如果中间的值小于要查找的值,说明要查找的值在后半部分,前下标移到中间位置的后一个位置 else lastnum = midnum; //如果中间的值大于要查找的值,说明要查找的值在前半部分,后下标移到中间位置 } if (lastnum < frontnum)//当前下标大于后下标时,说明没有找到 { cout << "Student information is not exit!" << endl; } else { //当前后下标指向同一个元素 mid = set_position(frontnum); if (mid->sroom == target) { cout << "sroom" << " "<< "sid" << " "<< "sname" << endl; cout << mid->sroom << " " << mid->sid << " " << mid->sname << endl; if(mid->next != NULL) { Node *p = mid->next; while(p && (p->sroom == mid->sroom))//查找后面还有没有相同的数据 { cout << p->sroom << " " << p->sid << " " << p->sname << endl; p = p->next; }//如果这个位置的值等于要查找的值,则该位置一定是在这个表中第一次出现的位置 } } else//如果不是则说明表中没有这个数据 { cout << "Student information is not exit!" << endl; } } } List::~List() //析构函数 { Node *p,*q; for(p = head;p;p = q) { q = p->next; delete p; } //遍历,有数据的释放空间 count = 0; head = NULL; //置空 }
main.cpp
#include <iostream> #include <fstream> #include "list.cpp" using namespace std; void print(List const &nowlist) //将线性表中的数据写入文件中 { ofstream ofs; ofs.open("student.txt",ios::out); ofs.clear(); Node *p; ofs << "sid" << " " << "sname" << " " << "sroom" << endl; for(int i = 0;i < nowlist.size();i++) { p = nowlist.set_position(i); ofs << p->sid << " " << p->sname << " " << p->sroom<< endl; } ofs.close(); } int main() { List list1; ofstream ofs; ofs.open("student.txt",ios::out); ofs << "sid" << " " << "sname" << " " << "sroom" << endl; int t = 1; char i = 0; cout << "---------------------------------------------------" << endl; cout << "欢迎进入宿舍查询软件" << endl; cout << "---------------------------------------------------" << endl; while(t) { cout << "1.插入学生信息 2.排序 3.查询 4.退出" << endl << "请选择要进行的操作:"; cin >> i; switch(i) { case '1': //插入学生信息 { Node newstu; cout << "请输入该学生的学号:"; cin >> newstu.sid; if(cin.fail()) { cout << "Please enter the correct number!" << endl; cin.clear(); //清除std::cin的错误状态 cin.sync(); //清空输入缓冲区 break; } cout << "请输入该学生的姓名:"; cin >> newstu.sname; cout << "请输入该学生的房号:"; cin >> newstu.sroom; if(cin.fail()) { cout << "Please enter the correct number!" << endl; cin.clear(); //清除std::cin的错误状态 cin.sync(); //清空输入缓冲区 break; } list1.insert(newstu); ofs << newstu.sid << " " << newstu.sname << " " << newstu.sroom<< endl; break; } case '2': //排序 { char ch; cout << "A.按姓名排序 B.按学号排序 C.按房号排序" << endl << "请选择排序的方式:"; cin >> ch; switch(ch) { case 'A': //按姓名排序 { list1.sname_sort(); print(list1); continue; } case 'B': // 按学号排序 { list1.sid_sort(); print(list1); continue; } case 'C': //按房号排序 { list1.sroom_sort(); print(list1); continue; } default: { cout << "无此选项,请重新选择" << endl; continue; } } } case '3': //查询 { char ch; cout << "A.按姓名查询 B.按学号查询 C.按房号查询 " << endl << "请选择查询的方式:"; cin >> ch; switch(ch) { case 'A': //按姓名查询 { string name; cout << "请输入要查询的学生的姓名:"; cin >> name; list1.sname_sort(); list1.snamebinary_search(name); continue; //问题:运行这部分完程序直接结束 } case 'B': //按学号查询 { int id; cout << "请输入要查询的学生的学号:"; cin >> id; if(cin.fail()) { cout << "Please enter the correct number!" << endl; cin.clear(); //清除std::cin的错误状态 cin.sync(); //清空输入缓冲区 break; } list1.sid_sort(); list1.sidbinary_search(id); continue; } case 'C': //按房号查询 { int room; cout << "请输入要查询的房号:"; cin >> room; if(cin.fail()) { cout << "Please enter the correct number!" << endl; cin.clear(); //清除std::cin的错误状态 cin.sync(); //清空输入缓冲区 break; } list1.sroom_sort(); list1.sroombinary_search(room); continue; } default: { cout << "无此选项,请重新选择" << endl; continue; } } } case '4': //退出 { t = 0; break; } default: { cout << "无此选项,请重新选择" << endl; break; } } } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。