链表保存学生的年龄和性别信息,应该说链表是学习C++必学的知识,但个人感觉操作还是挺麻烦的,而且如果链表长的话检索起来的速度可能会比较慢,代码中使用到了没遇到过的EXIT(0);效果应该是和RETURN NULL:差不多吧。总之,链表还是得自己多敲一下代码试试,否则即使是基础的东西也是学不了多少的。
/*
本程序由肖秀春编写,作为课堂教学演示用
*/
#include <iostream>
#include <stdlib.h>
#define LEN 20 //姓名、学号最大字符数
//定义单链表的一个结点,或称数据元素
struct link_node
{
//数据域
char stu_No[LEN+1]; // 学号
char stu_Name[LEN+1]; // 姓名
int stu_Age; // 年龄
char stu_Sex[2+1]; // 性别
float stu_Score1; // 成绩一
float stu_Score2; // 成绩二
float stu_Score3; // 成绩三
float stu_Score4; // 成绩四
float stu_Score5; // 成绩五
//指针域
link_node * next;
} ;
//定义单链表类
class link_Student
{
//定义成员变量
private:
//指针域
link_node * head;
int current_stuNum;
// 定义成员函数
public:
link_Student();// 构造函数
~link_Student();// 析构函数
int get_Current_stuNum();// 求当前单链表结点个数,即求学生数目
void insert_stu_Info(link_node * p1, int i);// 插入一个结点,即插入一个学生信息
void delete_stu_Info(int i);// 删除一个结点,即删除一个学生信息
link_node * get_stu_Info(int i);// 获取一个结点的信息,即获取某位置的学生信息
};
// 构造函数
link_Student::link_Student()
{
head=NULL;
current_stuNum=0;
}
// 析构函数,需要释放所动态申请的内存空间
link_Student::~link_Student()
{
link_node *p1,*p2;//p1为当前链表的头结点
p1=head;
while(p1!=NULL)
{
p2=p1;
p1=p1->next;
delete p2;
}
head=NULL;
}
// 求当前单链表结点个数,即求学生数目
int link_Student::get_Current_stuNum()
{
return current_stuNum;
}
// 插入一个结点,即插入一个学生信息
void link_Student::insert_stu_Info(link_node * p1, int pos)//(注:结点从1开始编号,pos表示插入操作后结点所处的位置:pos为1时,表示在单链表的头结点前插入;pos为current_stuNum+1时,表示在单链表的尾结点后插入)
{
//定义temp用来找出插入的前一个结点
link_node* temp=head;
//判断插入位置是否合法
if (pos<1 || pos>current_stuNum+1)
{
cout<<"所给插入的位置不正确,位置值不能是负数或超过当前元素个数+1!"<<endl;
exit(0);
}
if(pos==1)//pos为1时,表示在单链表的头结点前插入
{
head=p1;//新结点作为头结点
p1->next=temp;// 原链表中的后半部分链到新结点后面
}
else
{
if(pos==current_stuNum+1)//current_stuNum+1为1时,表示在单链表的尾结点后插入
{
//将要插入位置的前一个结点找出来
for (int j=1;j<pos-1;j++)
{
temp=temp->next;
}
temp->next=p1;// 新结点链到原链表中的前半部分后面
p1->next=NULL;//新结点作为尾结点,所以需要将其next置为NULL
}
else
{
//将要插入位置的前一个结点找出来
for (int j=1;j<pos-1;j++)
{
temp=temp->next;
}
p1->next=temp->next;// 原链表中的后半部分链到新结点后面
temp->next=p1;// 新结点链到原链表中的前半部分后面
}
}
//修改当前学生数
current_stuNum++;
}
// 删除一个结点,即删除一个学生信息
void link_Student::delete_stu_Info(int pos)//(注:结点从1开始编号,pos表示删除的结点所处的位置:pos为1时,表示删除单链表的头结点;pos为current_stuNum+1时,表示删除单链表的尾结点)
{
//定义temp用来找出删除结点的前一个结点
link_node* temp=head;
//判断位置是否合法
if (pos<1 || pos>current_stuNum)
{
cout<<"所给删除位置不正确,位置值不能是负数或超过当前元素个数!"<<endl;
exit(0);
}
if(pos==1)//pos为1时,表示删除单链表的头结点
{
head=head->next;// 链好
delete temp;// 删除
}
else
{
if(pos==current_stuNum)
{
//将要删除结点的前一个结点找出来
for (int j=1;j<pos-1;j++)
{
temp=temp->next;
}
delete temp->next;// 删除
temp->next=NULL;// 由于删除的是尾结点,因此尾结点前的一个结点成为尾结点,所以需要将其next置为NULL
}
else
{
//将要删除位置的前一个结点找出来
for (int j=1;j<pos-1;j++)
{
temp=temp->next;
}
link_node* temp2=temp->next;// 保存
temp->next=temp->next->next;// 链好
delete temp2;// 删除
}
}
//修改当前学生数
current_stuNum--;
}
// 获取一个结点的信息,即获取某位置的学生信息
link_node * link_Student::get_stu_Info(int pos)//(注:结点从1开始编号,pos表示删除的结点所处的位置:pos为1时,表示删除单链表的头结点;pos为current_stuNum+1时,表示删除单链表的尾结点)
{
//定义temp用来找出要获取信息的结点
link_node* temp=head;
//判断位置是否合法
if (pos<1 || pos>current_stuNum)
{
cout<<"所给出的要获取信息的位置不正确,位置值不能是负数或超过当前元素个数!"<<endl;
exit(0);
}
for (int j=1;j<pos;j++)
{
temp=temp->next;
}
return temp;
}
void main()
{
int i_nodeNum;
link_Student ls1;
cout<<"需要插入几个学生的信息?"<<endl;
cin>>i_nodeNum;
for (int j=1;j<=i_nodeNum;j++)
{
link_node * ln1=new link_node;
cout<<"请输入第"<<j<<"个学生的信息:"<<endl;
cout<<"年龄:";
cin>>ln1->stu_Age;
cout<<"性别:";
cin>>ln1->stu_Sex;
/*cout<<"姓名:";
cin>>ln1->stu_Name;
cout<<"学号:";
cin>>ln1->stu_No;
cout<<"成绩1:";
cin>>ln1->stu_Score1;
cout<<"成绩2:";
cin>>ln1->stu_Score2;
cout<<"成绩3:";
cin>>ln1->stu_Score3;
cout<<"成绩4:";
cin>>ln1->stu_Score4;
cout<<"成绩5:";
cin>>ln1->stu_Score5;*/
ls1.insert_stu_Info(ln1,j);
}
for (j=1;j<=i_nodeNum;j++)
{
cout<<ls1.get_stu_Info(j)->stu_Age<<endl;
cout<<ls1.get_stu_Info(j)->stu_Sex<<endl;
/*cout<<ls1.get_stu_Info(j)->stu_Name<<endl;
cout<<ls1.get_stu_Info(j)->stu_No<<endl;
cout<<ls1.get_stu_Info(j)->stu_Score1<<endl;
cout<<ls1.get_stu_Info(j)->stu_Score2<<endl;
cout<<ls1.get_stu_Info(j)->stu_Score3<<endl;
cout<<ls1.get_stu_Info(j)->stu_Score4<<endl;
cout<<ls1.get_stu_Info(j)->stu_Score5<<endl;
*/
}
for (j=i_nodeNum;j>=1;j--)
{
ls1.delete_stu_Info(j);
cout<<ls1.get_Current_stuNum()<<endl;
}
}