/*题目:基于链表的学生信息管理系统
要求:
(1)插入节点:输入学生信息后,生成节点并插入链表中;
(2)删除节点:根据给定的学生姓名或学号删除该学生节点;
(3)查找节点:根据给定的学生姓名或学号查找学生信息,并显示出来;
(4)查找并显示总成绩最高和最低的学生信息;
(5)统计链表中的学生人数;
(6)(时间允许时选做) 对链表节点按总成绩从高到低排序。
注:
(1)每个学生信息包括:姓名、学号、性别、出生年月日和3门课的成绩;
(2)系统运行后,首先显示一个简易的菜单,基于菜单操作来完成上述功能;
(3)链表的功能需要编程实现。*/
#include
#include
#include
using namespace std;
class Date
{
private:
unsigned short int year;
unsigned short int month;
unsigned short int day;
public:
bool CheckDate(int y, int m, int d);
friend istream &operator>>(istream &is, Date &d);
friend ostream &operator<<(ostream &os, const Date &d);
Date& operator=(const Date&d);
};
bool Date::CheckDate(int y, int m, int d)
{
int n;//最大天数
if (m<1 || m>12) return false;
if (d<1) return false;
n = 31;
switch (m)
{
case 2:
if (y % 4 == 0 && y % 100 || y % 400 == 0)//判断是否是闰年
n = 29;
else
n = 28;
break;
case 4:
case 6:
case 9:
case 11:
n = 30;
break;
}
if (d > n) return false;
return true;
}
istream &operator>>(istream &is, Date &d)
{
is >>d.year >> d.month >> d.day;
while (d.CheckDate(d.year, d.month, d.day) == false) {
cout << "出生年月日输入错误!请重新输入:" << endl;
is >> d.year >> d.month >> d.day;
}
return is;
}
ostream &operator<<(ostream &os, const Date &d)
{
os << d.year << "/" << d.month << "/" << d.day ;
return os;
}
Date& Date::operator=(const Date&d)
{
year = d.year;
month = d.month;
day = d.day;
return *this;
}
/*------------------------------------------------------------*/
class Student
{
private:
string name;
string number;
char gender;
Date date;
float score1, score2, score3;
float sum;
public:
Student *next;
Student();
~Student();
void operator=(const Student& stu);
void input();
void disp();
friend class LinkList;
};
Student::Student()
{
next = nullptr;
}
Student::~Student(){}
void Student::operator=(const Student& stu)
{
name = stu.name;
number = stu.number;
gender = stu.gender;
date = stu.date;
score1 = stu.score1;
score2 = stu.score2;
score3 = stu.score3;
sum = stu.sum;
}
void Student::input()
{
cout << "请依次输入姓名,学号,性别(M(男)/F(女)),出生年月日:" << endl;
cin >> name >> number >> gender >> date;
while (gender != 'M' && gender != 'F' ) {
cout << "性别输入错误!请重新输入:" << endl;
cin >> gender;
}
cout << "请输入三门课程成绩:";
cin >> score1 >> score2 >> score3;
sum = score1 + score2 + score3;
}
void Student::disp()
{
cout << "|*------------------------------------------------------*|" << endl;
cout << "姓名:" << name << '\t' << "学号:" << number << endl;
cout << "性别:" << gender << '\t' << '\t' << "出生年月日:" << date << endl;
cout << "三门课程成绩:" << score1 << '\t' << score2 << '\t' << score3 << endl;
cout << "总分:" << sum << endl;
cout << "|*------------------------------------------------------*|" << endl;
}
class LinkList
{
private:
Student * head;
Student * last;
static float count;
public:
LinkList();
~LinkList();
void Append(Student stu);
void Delete(string s);
void Find(string s);
void Extrnum();
Student* Max(Student *ptr);
void Sort();
void Count();
};
float LinkList::count = 0;
LinkList::LinkList()
{
head = new Student;
last = head;
last->next = nullptr;
}
LinkList::~LinkList()
{
delete head;
}
void LinkList::Append(Student stu)
{
cout << "插入节点!" << endl;
Student *pnew = new Student;
*pnew = stu;
pnew->next = nullptr;
last->next = pnew;
last = last->next;
LinkList::count ++;
}
void LinkList::Delete(string s)
{
char flag = 'N';
Student *temp = head;
while (temp != last) {
if (temp->next->name == s || temp->next->number == s) {
temp->next->disp();
cout << "是否确认删除该学生信息?(Y/N):";
cin >> flag;
while (flag != 'Y' && flag != 'N') {
cout << "请输入正确指令:";
cin >> flag;
}
if (flag == 'Y') {
cout << "删除节点!" << endl;
Student *del = temp->next;
temp->next = temp->next->next;
del->~Student();
LinkList::count--;
}
}
temp = temp->next;
}
}
void LinkList::Find(string s)
{
int flag = 0;
Student *pfind = head->next;
while (pfind != nullptr) {
if (pfind->name == s || pfind->number == s) {
flag++;
cout << "符合学生信息" << flag << ":" << endl;
pfind->disp();
}
pfind = pfind->next;
}
if (flag == 0) cout << "查无此人!" << endl;
}
void LinkList::Extrnum()
{
cout << "查找并显示总成绩最高和最低的学生信息:" << endl;
float min_sum = 1000.0f;
float max_sum = 0.0f;
Student* temp = head->next;
/*可能存在最高或最低成绩相同的学生,分两次遍历*/
while (temp != nullptr) {
if (temp->sum < min_sum) min_sum = temp->sum;
else if (temp->sum > max_sum) max_sum = temp->sum;
temp = temp->next;
}
temp = head->next;
while (temp != nullptr) {
if (temp->sum == min_sum) {
cout << "总成绩最低学生信息:" << endl;
temp->disp();
}
else if (temp->sum == max_sum) {
cout << "总成绩最高学生信息:" << endl;
temp->disp();
}
temp = temp->next;
}
}
Student* LinkList::Max(Student *ptr)
{
Student *p = ptr;
Student *pmax = p;
while (p != nullptr) {
if (p->sum > pmax->sum) {
pmax = p;
}
p = p->next;
}
return pmax;
}
void LinkList::Sort()
{
Student *p = head->next;
Student *r = nullptr;
while (p != nullptr) {
r = Max(p);
Student stu = *p;
*p = *r;
*r = stu;
p = p->next;
}
p = head->next;
cout << "排序后链表:" << endl;
while (p != nullptr) {
p->disp();
p = p->next;
}
}
void LinkList::Count()
{
cout << "链表中学生人数:" << LinkList::count << endl;
}
int main()
{
LinkList llist;
int order = 0;
string s;
Student stu;
while (order != 6) {
cout << "|*------------------学生信息管理系统--------------------*|" << endl;
cout << "| 输入0:插入节点 |" << endl;
cout << "| 输入1:删除节点 |" << endl;
cout << "| 输入2:查找节点 |" << endl;
cout << "| 输入3:查找并显示总成绩最高和最低的学生信息 |" << endl;
cout << "| 输入4:统计链表中的学生人数 |" << endl;
cout << "| 输入5:对链表节点按总成绩从高到低排序 |" << endl;
cout << "| 输入6:退出系统 |" << endl;
cout << "|*------------------------------------------------------*|" << endl;
cin >> order;
switch (order) {
case 0:
stu.input();
llist.Append(stu);
break;
case 1:
cout << "请输入要删除的学生姓名或学号:" << endl;
cin >> s;
llist.Delete(s);
break;
case 2:
cout << "请输入要查找的学生姓名或学号:" << endl;
cin >> s;
llist.Find(s);
break;
case 3:
llist.Extrnum();
break;
case 4:
llist.Count();
break;
case 5:
llist.Sort();
break;
case 6:
cout << "退出系统!" << endl;
break;
default:
cout << "输入错误信息!请重新输入。" << endl;
cin >> order;
break;
}
}
system("pause");
return 0;
}