首先运用面向对象的思想和方法,定义一个学生类。该类中有数据成员学生姓名,性别,专业,出生日期,家庭地址,英语入学成绩。
//学生类
class Student {
public:
void stu_Name(string Name) {
this->Name=Name;
}
void stu_Sex(string Sex) {
this->Sex=Sex;
}
void stu_Major(string Major) {
this->Major=Major;
}
void stu_Year(int Year) {
this->Year=Year;
}
void stu_Month(int Month) {
this->Month=Month;
}
void stu_Day(int Day) {
this->Day=Day;
}
void stu_Adress(string Adress) {
this->Adress=Adress;
}
void stu_Score(int Score) {
this->Score=Score;
}
string get_Name() {
return Name;
}
string get_Sex() {
return Sex;
}
string get_Major() {
return Major;
}
int get_Year() {
return Year;
}
int get_Month() {
return Month;
}
int get_Day() {
return Day;
}
string get_Adress() {
return Adress;
}
int get_Score() {
return Score;
}
private:
string Name;
string Sex;
string Major;
int Year;
int Month;
int Day;
string Adress;
int Score;
};
再根据学生信息存储结构,定义学生信息的结点类型,其中创建了一个新生类对象s,用来存放节点中的数据域,next是指针类型的成员,他指向struct StuNode类型的数据,用来存放下一个结点的地址,属于结点中的指针域。
typedef struct StuNode {
Student s;
struct StuNode *next;
} stu;
再定义一个链表类,链表类中的成员函数有创建单链表,输出单链表,删除单链表结点,通过姓名查询将链表中的其中一个结点输出,按性别、专业、年龄排序,保存链表中的信息。
//链表类
class StuListLink {
public:
void add();
void print();
void Delete();
void Sort();
void Look();
void sta_Sex();
void sta_Major();
void sta_Age();
void Save();
private:
stu *head;
stu *tail;
int count;
};
其中创建链表时,先输入需要录入的新生个数,再依次输入新生的各种信息,其中在输入新生性别时只能录入男或女,会通过字符串比较输入的数据是否为男或女,如果输入的格式不为男或女,将输出“输入有误,请重新输入”,此时要继续输入新生性别。在输入新生的出生日期时要依次输入新生出生日期的年、月、日,其中年份必须在2000~2021的范围内,月份必须在1~12的范围内,日期必须在1~31的范围内,最后再将刚才输入的信息存入链表结点中的数据域,接着输入下一位新生的信息,录入完毕后,将最后一个结点的数据域赋值为NULL,链表创建成功。
void StuListLink::add() {
stu *p;
cout<<"请输入学生总数:"<<endl;
cin>>count;
if(count<0) {
cout<<"错误,总数不能小于0"<<endl;
return;
}
head=new stu;
head->s.stu_Name("\0");
head->s.stu_Sex("\0");
head->s.stu_Major("\0");
head->s.stu_Year(0);
head->s.stu_Month(0);
head->s.stu_Day(0);
head->s.stu_Adress("\0");
head->s.stu_Score(0);
head->next =NULL;
tail=head;
for(int i=0; i<count; i++) {
cout<<"请输入第"<<i+1<<"个学生的信息"<<endl;
p=new stu;
cout<<"请输入学生姓名"<<endl;
string c1;
cin>>c1;
p->s.stu_Name(c1);
cout<<"请输入学生性别"<<endl;
cin>>c1;
while(c1!="男"&&c1!="女") {
cout<<"输入有误,请重新输入"<<endl;
cin>>c1;
}
p->s.stu_Sex(c1);
cout<<"请输入学生专业"<<endl;
cin>>c1;
p->s.stu_Major(c1);
cout<<"请输入学生出生日期\n年:"<<endl;
int i1;
cin>>i1;
while(i1<2000||i1>2021) {
cout<<"输入有误,请重新输入"<<endl;
cin>>i1;
}
p->s.stu_Year(i1);
cout<<"月:"<<endl;
cin>>i1;
while(i1<1||i1>12) {
cout<<"输入有误,请重新输入"<<endl;
cin>>i1;
}
p->s.stu_Month(i1);
cout<<"日:"<<endl;
cin>>i1;
while(i1<1&&i1>31) {
cout<<"输入有误,请重新输入"<<endl;
cin>>i1;
}
p->s.stu_Day(i1);
cout<<"请输入学生住址"<<endl;
cin>>c1;
p->s.stu_Adress(c1);
cout<<"请输入学生成绩"<<endl;
cin>>i1;
p->s.stu_Score(i1);
p->next=NULL;
tail->next=p;
tail=p;
}
cout<<"学生信息添加成功,一共添加"<<count<<"个学生的信息"<<endl;
system("pause");
}
输出链表是将链表中的各个结点依次遍历,读取出节点中数据域里的学生类中的各个数据,并通过一定格式依次打印出全部新生信息。
//打印全部学生信息
void StuListLink::print() {
stu *p=head;
p=p->next;
int a=0;
while(p!=NULL) {
a++;
cout<<a<<".\n"<<"学生姓名: "<<p->s.get_Name()<<"\n学生性别: "<<p->s.get_Sex()<<"\n学生专业: "<<p->s.get_Major()<<"\n学生出生日期:年/月/日 "<<p->s.get_Year()<<"/"<<p->s.get_Month()<<"/"<<p->s.get_Day()<<"\n学生住址: "<<p->s.get_Adress()<<"\n学生英语成绩: "<<p->s.get_Score()<<"\n\n"<<endl;
p=p->next;
}
system("pause");
}
通过姓名查找是先输入你需要查找的新生的姓名,再遍历链表,通过字符串的比较,找出与刚输入的姓名相同的新生,并打印出该新生的全部信息。如果遍历完整个链表还未找到输入的新生的名字,则输出“没有该学生”。
//按姓名查找学生
void StuListLink::Look() {
stu *p,*p1;
p=head;
p1=p->next;
cout<<"请输入要查找学生的姓名:"<<endl;
string N1;
cin>>N1;
while(p1!=NULL) {
if(p1->s.get_Name()==N1) {
cout<<"学生姓名: "<<p1->s.get_Name()<<"\n学生性别: "<<p1->s.get_Sex()<<"\n学生专业: "<<p1->s.get_Major()<<"\n学生出生日期:年/月/日 "<<p1->s.get_Year()<<"/"<<p1->s.get_Month()<<"/"<<p1->s.get_Day()<<"\n学生住址: "<<p1->s.get_Adress()<<"\n学生英语成绩: "<<p1->s.get_Score()<<"\n\n"<<endl;
cout<<"查找完毕"<<endl;
system("pause");
return;
}
p=p1;
p1=p->next;
}
if(p1=NULL) {
cout<<"没有该学生!"<<endl;
system("pause");
}
}
删除结点是先输入你需要删除的新生的姓名,再遍历链表,通过字符串的比较,找出与刚输入的姓名相同的新生,找出存放该新生信息的结点p1,和该结点的前驱结点p,然后将此前驱节点的指针域指向待删除节点的后续结点,最后释放被删除结点的所占空间,此时删除成功。如果遍历完整个链表还未找到输入的新生的名字,则输出“没有该学生”。
//删除学生信息
void StuListLink::Delete() {
stu *p,*p1;
p=head;
p1=p->next;
cout<<"请输入要删除学生的姓名:"<<endl;
string N1;
cin>>N1;
while(p1!=NULL) {
if(p1->s.get_Name()==N1) {
p->next=p1->next;
delete p1;
cout<<"删除成功:"<<endl;
system("pause");
return;
}
p=p1;
p1=p->next;
}
if(p1=NULL) {
cout<<"没有该学生!"<<endl;
system("pause");
}
}
统计性别、专业、年龄都是先输入想要统计的男女,什么专业,什么年龄,再遍历链表,找出链表结点中存放的与想要统计的类型相同的新生,并打印出所有符合条件的新生的信息,再遍历前定义一个int型数据k=0,每当找出一位符合类型的新生k就会自加1,最后输出k,代表有k个人符合该条件,达到统计新生信息的目的。其中年龄统计要先、通过新生生日计算出新生的年龄,再用计算出的年龄与输入的年龄相比较,具体实现方法就是用当前年份(2021)减去新生的出生日期,计算出新生的年龄,再实现统计。
//统计性别
void StuListLink::sta_Sex() {
stu *p,*p1;
p=head;
p1=p->next;
cout<<"请输入要统计的性别:"<<endl;
string S1;
cin>>S1;
int k=0;
while(p1!=NULL) {
if(p1->s.get_Sex()==S1) {
k++;
cout<<"学生姓名: "<<p1->s.get_Name()<<"\n学生性别: "<<p1->s.get_Sex()<<"\n学生专业: "<<p1->s.get_Major()<<"\n学生出生日期:年/月/日 "<<p1->s.get_Year()<<"/"<<p1->s.get_Month()<<"/"<<p1->s.get_Day()<<"\n学生住址: "<<p1->s.get_Adress()<<"\n学生英语成绩: "<<p1->s.get_Score()<<"\n\n"<<endl;
}
p=p1;
p1=p->next;
}
cout<<"有"<<k<<"个"<<S1<<"生"<<endl;
system("pause");
}
//统计专业
void StuListLink::sta_Major() {
stu *p,*p1;
p=head;
p1=p->next;
cout<<"请输入要统计的专业:"<<endl;
string M1;
cin>>M1;
int k=0;
while(p1!=NULL) {
if(p1->s.get_Major()==M1) {
k++;
cout<<"学生姓名: "<<p1->s.get_Name()<<"\n学生性别: "<<p1->s.get_Sex()<<"\n学生专业: "<<p1->s.get_Major()<<"\n学生出生日期:年/月/日 "<<p1->s.get_Year()<<"/"<<p1->s.get_Month()<<"/"<<p1->s.get_Day()<<"\n学生住址: "<<p1->s.get_Adress()<<"\n学生英语成绩: "<<p1->s.get_Score()<<"\n\n"<<endl;
}
p=p1;
p1=p->next;
}
cout<<M1<<"专业有"<<k<<"个人"<<endl;
system("pause");
}
//统计年龄
void StuListLink::sta_Age() {
stu *p,*p1;
p=head;
p1=p->next;
cout<<"请输入要统计的年龄:"<<endl;
int A1;
cin>>A1;
int k=0;
while(p1!=NULL) {
if((2021-p1->s.get_Year())==A1) {
k++;
cout<<"学生姓名: "<<p1->s.get_Name()<<"\n学生性别: "<<p1->s.get_Sex()<<"\n学生专业: "<<p1->s.get_Major()<<"\n学生出生日期:年/月/日 "<<p1->s.get_Year()<<"/"<<p1->s.get_Month()<<"/"<<p1->s.get_Day()<<"\n学生住址: "<<p1->s.get_Adress()<<"\n学生英语成绩: "<<p1->s.get_Score()<<"\n\n"<<endl;
}
p=p1;
p1=p->next;
}
cout<<"年龄为"<<A1<<"的有"<<k<<"个人"<<endl;
system("pause");
}
//统计信息
void Statistics() {
cout<<"请选择需要统计的内容"<<endl;
cout<<"统计性别按1\n"<<"统计专业按2\n"<< "统计年龄按3"<<endl;
int m;
cin>>m;
switch(m) {
case 1:
L.sta_Sex();
break;
case 2:
L.sta_Major();
break;
case 3:
L.sta_Age();
break;
}
}
按照成绩排序实现新生英语成绩从高到低依次排序,通过冒泡排序实现,遍历链表,比较两个相邻节点中存放的新生成绩的大小如果前一个成绩小于下一个,则交换两个结点的位置,否则继续向后比较。在排序完成后,按照成绩从高到低的顺序依次打印出新生信息。
//按英语成绩排序
void StuListLink::Sort() {
stu *p,*p1,*q;
p=head;
p1=head->next;
system("cls");
while(p->next!=NULL) { //冒泡排序
while(p1->next!=NULL) {
if(p->s.get_Score()<p1->s.get_Score()) {
q=p->next;
p->next=p1->next;
p1->next=p1->next->next;
p->next->next=q;
} else {
p1=p1->next;
}
}
p=p->next;
p1=p->next;
}
cout<<"已按学生成绩从高到低排序"<<endl;
system("pause");
p=head->next ;
int a=0;
while(p!=NULL) {
a++;
cout<<a<<".\n"<<"学生姓名: "<<p->s.get_Name()<<"\n学生性别: "<<p->s.get_Sex()<<"\n学生专业: "<<p->s.get_Major()<<"\n学生出生日期:年/月/日 "<<p->s.get_Year()<<"/"<<p->s.get_Month()<<"/"<<p->s.get_Day()<<"\n学生住址: "<<p->s.get_Adress()<<"\n学生英语成绩: "<<p->s.get_Score()<<"\n\n"<<endl;
p=p->next;
}
system("pause");
}
保存新生信息是通过文件操作将链表中的新生信息按照一定格式保存至电脑中的D盘中。
//保存学生信息
void StuListLink::Save() {
ofstream outfile("D:\\xsxx.txt");
stu *p=head->next;
int a=0;
while(p!=NULL) {
a++;
outfile<<a<<".\n"<<"学生姓名: "<<p->s.get_Name()<<"\n学生性别: "<<p->s.get_Sex()<<"\n学生专业: "<<p->s.get_Major()<<"\n学生出生日期:年/月/日 "<<p->s.get_Year()<<"/"<<p->s.get_Month()<<"/"<<p->s.get_Day()<<"\n学生住址: "<<p->s.get_Adress()<<"\n学生英语成绩: "<<p->s.get_Score()<<"\n\n"<<endl;
p=p->next;
}
outfile.close();
cout<<"学生信息保存成功"<<endl;
system("pause");
}
下面为主函数,里面包括菜单的打印和分支选择结构实现各个功能的选择。
int main() {
char a;
while(1) {
system("cls");
cout<<"\t\t\t\t\t**************************\n";
cout<<"\t\t\t\t\t* 欢迎使用学生管理系统 *\n";
cout<<"\t\t\t\t\t* 请选择想要使用的功能 *\n";
cout<<"\t\t\t\t\t* 添加学生信息请按1 *\n";
cout<<"\t\t\t\t\t* 查看学生信息请按2 *\n";
cout<<"\t\t\t\t\t* 按照姓名查找学生请按3 *\n";
cout<<"\t\t\t\t\t* 按照成绩排序请按4 *\n";
cout<<"\t\t\t\t\t* 删除学生信息请按5 *\n";
cout<<"\t\t\t\t\t* 统计学生信息请按6 *\n";
cout<<"\t\t\t\t\t* 保存学生信息请按7 *\n";
cout<<"\t\t\t\t\t* 退出系统请按8 *\n";
cout<<"\t\t\t\t\t**************************\n";
cin>>a;
switch(a) {
case '1':
system("cls");
L.add();
break;
case '2':
system("cls");
L.print();
break;
case '3':
system("cls");
L.Look() ;
break;
case '4':
system("cls");
L.Sort();
break;
case '5':
system("cls");
L.Delete();
break;
case '6':
system("cls");
Statistics();
break;
case '7':
system("cls");
L.Save();
break;
case '8':
exit(0);
break;
default :
system("cls");
printf("输入方式错误,请重新输入!\n");
system("pause");
break;
}
}
return 0;
}
|