//题目:基于链表的学生信息管理系统
//要求:
// (1)插入节点:输入学生信息后,生成节点并插入链表中;
// (2)删除节点:根据给定的学生姓名或学号删除该学生节点;
// (3)查找节点:根据给定的学生姓名或学号查找学生信息,并显示出来;
// (4)查找并显示总成绩最高和最低的学生信息;
// (5)统计链表中的学生人数;
// (6)(时间允许时选做)对链表节点按总成绩从高到低排序。
// 注:
// (1)每个学生信息包括:姓名、学号、性别、出生年月日和3门课的成绩;
// (2)系统运行后,首先显示一个简易的菜单,基于菜单操作来完成上述功能;
// (3)链表的功能需要编程实现。
#include<iostream>
#include<string>
using namespace std;
class Date//日期类
{
private:
unsigned short int year;
unsigned short int month;
unsigned short int day;
public:
bool CheckDate()
{
//检查年月日是否出错
int max=31;
if(month<1||month>12) return false;
if(year<0) return false;
switch(month)
{
//一月大 二月特 三月大 四月小 五月大 六月小 78大 九月小 十月大 十一月小 十二月大
case 2:if(year % 4 == 0 && year % 100 || year % 400 == 0) //如果是闰年
max= 29;
else max = 28;
case 4:
case 6:
case 9:
case 11:max =30;
}
if(day>max) return false;
return true;
}
friend istream &operator>>(istream &cin, Date &date)//输入流修改
{
cin >> date.year >>date.month >> date.day;//cin是 istream的一个对象
while(date.CheckDate()==false)
{
cout<<"出生年月日输入错误,请重新输入"<<endl;
cin >> date.year >>date.month >> date.day;
}
return cin;
}
friend ostream &operator<<(ostream &cout, const Date &date)
{
cout<<date.year<<"/"<<date.month<<"/"<<date.day;
return cout;
}
Date& operator=(const Date &date)
{
year=date.year;
month = date.month;
day=date.day;
return *this;
}
};
class Student//学生结点
{
private:
friend class StudentList;//结点是大类的友元 这样方便
Student *next;//后继
string name;
string number;
char gender;//性别 省空间
Date date;//出生年月日类 稍后再设置 还要确认是否错误
float score1,score2,score3;
float sum;//总分
public:
Student(){next = NULL;}//构造函数
~Student(){};//析构函数
void 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 input(string name_,string number_)//输入单个学生属性
{
// {cout<<"请依次输入姓名,学号:";
// cin>>name>>number;
this->name=name_;this->number=number_;
cout<<"请输入性别(M or m(男)/F or f (女)):";
cin>>gender;
while(gender!='M'&&gender!='F'&&gender!='m'&&gender!='f')
{
cout<<"性别输入错误,请重新输入!!"<<endl;
cin>>gender;
}
cout<<"请输入出生年月日(例如1999 12 31):";
cin>>date;
cout<<"请输入三门课的成绩:";
cin>>score1>>score2>>score3;
sum = score1+score2+score3;
}
void disp()//输出单个学生属性
{
cout<<"--------------------------------------------------------------"<<endl;
cout<<"姓名:"<<name<<"\t"<<"学号:"<<number<<endl;
cout<<"性别:";
if(gender=='m'||gender=='M')
cout<<'M';
else
cout<<'F';
cout<<"\t\t"<<"出生年月日:"<<date<<endl;
cout<<"三门课成绩:"<<endl<<"score1="<<score1<<endl<<"score2="<<score2<<endl<<"score3="<<score3<<endl;
cout<<"总分为:"<<sum<<endl;
cout<<"--------------------------------------------------------------"<<endl;
}
};
class StudentList
{
protected:
Student *first;
Student *last;
unsigned int count;
public:
StudentList()//构造函数
{
first=last=new Student;
count = 0;
}
~StudentList()//析构函数 删除所有new
{
Clear();
delete first;
}
//功能区
//题目:基于链表的学生信息管理系统
//要求:
// (1)插入节点:输入学生信息后,生成节点并插入链表中;
// (2)删除节点:根据给定的学生姓名或学号删除该学生节点;
// (3)查找节点:根据给定的学生姓名或学号查找学生信息,并显示出来;
// (4)查找并显示总成绩最高和最低的学生信息;
// (5)统计链表中的学生人数;
// (6)(时间允许时选做)对链表节点按总成绩从高到低排序。
// 注:
// (1)每个学生信息包括:姓名、学号、性别、出生年月日和3门课的成绩;
// (2)系统运行后,首先显示一个简易的菜单,基于菜单操作来完成上述功能;
// (3)链表的功能需要编程实现。
void Append()//表尾插入结点 头节点为空
{
Student *pointer = new Student;
string name_,number_;
cout<<"请依次输入姓名,学号:";
cin>>name_>>number_;
//判断学号是否重复
// bool found_number = false
for(Student* pointer1=first;pointer1!=last;pointer1=pointer1->next)
{
if(pointer1->next->number == number_)
{
cout<<"该学号已存在于表中,信息如下,请核实"<<endl;
pointer1->next->disp();
return;
}
}
// if(found_number){
// cout<<"该学号已存在,信息如下:"<<endl;
//
// }
pointer->input(name_,number_);
pointer->next = NULL;
last->next = pointer;
last = last->next;
this->count ++;
}
void Delete()//根据输入的s(姓名或学号)删除学生节点
{
string s;
int k=0;//跳出标志
bool Find=false;
cout<<"请输入需要删除的学生姓名或学号:";
cin>>s;
char flag = 'N';//删除标签
Student *pointer = first;
if(count !=0)
for(;pointer!=last;pointer=pointer->next)
{
if(pointer->next->name == s||pointer->next->number == s)
{
Find=true;
pointer->next->disp();
cout<<"确认删除?(Y/N):"<<endl;
cin>>flag;
while(flag!='Y'&&flag!='N'&&flag!='y'&&flag!='n')
{
cout<<"输入错误,请重新输入Y/N"<<endl;
cin>>flag;
}
if(flag=='Y'||flag=='y')
{
if(pointer->next->next==NULL)
last=pointer;
Student* temp = pointer->next->next;
delete pointer->next;
pointer->next = temp;
this->count--;
cout<<"删除成功!"<<endl;
k=1;
}
else
{
cout<<"已取消删除!."<<endl;
k=1;
}
}
if(k == 1)
break;
}
if(Find == false)
cout<<"很遗憾,没有您想删除的这个人"<<endl;
}
void Find()//根据给定的学生姓名或学号查找学生信息,并显示出来
{
string s;
cout<<"请输入需要寻找的学生姓名或学号:";
cin>>s;
bool found=false;
Student *pointer =first;
for(;pointer!=last;pointer=pointer->next)
{
if(pointer->next->name==s||pointer->next->number == s)
{
pointer->next->disp();
found=true;
break;
}
}
if(found == false) cout<<"很遗憾,没有您要找的人"<<endl;
}
void HighLowStudent()//查找并显示总成绩最高和最低的学生信息;
{
//一次遍历寻找最大最小值
//二次遍历输出(因为可能有多个人)
if(count == 0 )
{
cout<<"空表!"<<endl;
return;
}
cout<<"查找并显示总成绩最高和最低的学生信息。"<<endl;
float MAXSUM=0,MINSUM=10000;
Student *pointer=first->next;
for(;pointer!=NULL;pointer=pointer->next)
{
if(pointer->sum>MAXSUM) MAXSUM=pointer->sum;
if(pointer->sum<MINSUM) MINSUM=pointer->sum;
}
cout<<"最大总分为:"<<MAXSUM<<",最小总分为"<<MINSUM<<endl;
for(pointer=first->next;pointer!=NULL;pointer=pointer->next)
{
if(pointer->sum==MAXSUM){
cout<<"总成绩最高的同学信息为:"<<endl;
pointer->disp();
}
}
for(pointer=first->next;pointer!=NULL;pointer=pointer->next)
{
if(pointer->sum==MINSUM){
cout<<"总成绩最低的同学信息为:"<<endl;
pointer->disp();
}
}
}
//void Count();//统计链表中的学生人数
void Sort()//对链表节点按总成绩从高到低排序
{
if(count == 0){cout<<"空表!"<<endl;return;}
if(count >0){
Student *pointer = first->next;
for(int i=0;i<count-1;i++,pointer=first->next){
for(int j=0;j<count-1-i;j++,pointer=pointer->next){
if(pointer->sum<pointer->next->sum){
Student temp;
temp=*pointer;
*pointer=*(pointer->next);
*(pointer->next)=temp;
}
}
}
}
cout<<"----------------------排序后输出结果--------------------"<<endl;
for(Student *pointer=first->next;pointer!=NULL;pointer=pointer->next){
pointer->disp();
}
}
void Clear()//删去所有结点
{
Student *pointer = first;
while(pointer!=last)
{
Student *next = pointer->next;
delete pointer;
pointer = next;
}
first=last;
}
int get_count()
{
return count;
}
};
int main(){
int x=-1;
StudentList happystudent;
cout<<"---------------请输入对应数字,完成对应功能---------------"<<endl;
cout<<"0.退出程序"<<endl;
cout<<"1.插入节点:输入学生信息后,生成节点并插入链表中。"<<endl;
cout<<"2.删除节点:根据给定的学生姓名或学号删除该学生节点。"<<endl;
cout<<"3.查找节点:根据给定的学生姓名或学号查找学生信息,并显示出来。"<<endl;
cout<<"4.查找并显示总成绩最高和最低的学生信息。"<<endl;
cout<<"5.统计链表中的学生人数。"<<endl;
cout<<"6.对链表节点按总成绩从高到低排序。"<<endl;
cout<<"7.再次显示索引菜单"<<endl;
cout<<"----------------------------------------------------------"<<endl;
cout<<""<<endl;
cout<<"数字指令输入:";
cin>>x;
while(x){
switch(x){
case 0:
x=0;
cout<<"程序已退出"<<endl;
break;
case 1:
happystudent.Append();
cout<<"请再次输入对应数字,完成对应功能:";
cin>>x;
break;
case 2:
happystudent.Delete();
cout<<"请再次输入对应数字,完成对应功能:";
cin>>x;
break;
case 3:
happystudent.Find();
cout<<"请再次输入对应数字,完成对应功能:";
cin>>x;
break;
case 4:
happystudent.HighLowStudent();
cout<<"请再次输入对应数字,完成对应功能:";
cin>>x;
break;
case 5:
cout<<"学生链表中的学生人数为"<<happystudent.get_count()<<endl;
cout<<"请再次输入对应数字,完成对应功能:";
cin>>x;
break;
case 6:happystudent.Sort();
cout<<"请再次输入对应数字,完成对应功能:";
cin>>x;
break;
case 7:
cout<<"---------------请输入对应数字,完成对应功能---------------"<<endl;
cout<<"0.退出程序"<<endl;
cout<<"1.插入节点:输入学生信息后,生成节点并插入链表中。"<<endl;
cout<<"2.删除节点:根据给定的学生姓名或学号删除该学生节点。"<<endl;
cout<<"3.查找节点:根据给定的学生姓名或学号查找学生信息,并显示出来。"<<endl;
cout<<"4.查找并显示总成绩最高和最低的学生信息。"<<endl;
cout<<"5.统计链表中的学生人数。"<<endl;
cout<<"6.对链表节点按总成绩从高到低排序。"<<endl;
cout<<"7.再次显示索引菜单"<<endl;
cout<<"----------------------------------------------------------"<<endl;
cout<<""<<endl;
cout<<"数字指令输入:";
cin>>x;
break;
default:
cout<<"输入错误!请再次输入对应数字,完成对应功能:";
cin>>x;
break;
}
}
return 0;
}