编程马拉松(12)链表
还是11题的内容,但用连表方式实现#include <iostream>
using namespace std;
struct test
{
int number;
char name;
float shuxue;
float yuwen;
float yingyu;
float wule;
float huaxue;
float zongfen()
{
return shuxue+yuwen+wule+huaxue+yingyu;
};
test *next;
const struct test& operator=(const struct test &a)//这里用到了,运算符重载,以后会讲。
{
number = a.number;
strcpy(name, a.name);
shuxue = a.shuxue;
yuwen = a.yuwen;
yingyu = a.yingyu;
wule = a.wule;
huaxue = a.huaxue;
return *this;
}
};
test *head;//创建一个全局的引导进入链表的指针
test *create()//输入数据
{
test *ls;//节点指针
test *le;//链尾指针
ls = new test;//把ls指向动态开辟的堆内存地址
cout<<"请输入第一个学生数据,输入所有项为0退出"<<endl;
cout<<"学号:";
cin>>ls->number;
cout<<"姓名:";
cin>>ls->name;
cout<<"数学:";
cin>>ls->shuxue;
cout<<"语文:";
cin>>ls->yuwen;
cout<<"英语:";
cin>>ls->yingyu;
cout<<"物理:";
cin>>ls->wule;
cout<<"化学:";
cin>>ls->huaxue;
head=NULL;//进入的时候先不设置head指针指向任何地址,因为不知道是否一上来就输入null跳出程序
le=ls;//把链尾指针设置成刚刚动态开辟的堆内存地址,用于等下设置le->next,也就是下一个节点的位置
while(ls->number!=0)//创建循环条件为ls->number的值不是null,用于循环添加节点
{
if(head==NULL)//判断是否是第一次进入循环
{
head=ls;//如果是第一次进入循环,那么把引导进入链表的指针指向第一次动态开辟的堆内存地址
}
else
{
le->next=ls;//如果不是第一次进入那么就把上一次的链尾指针的le->next指向上一次循环结束前动态创建的堆内存地址
}
le=ls;//设置链尾指针为当前循环中的节点指针,用于下一次进入循环的时候把上一次的节点的next指向上一次循环结束前动态创建的堆内存地址
ls=new test;//为下一个节点在堆内存中动态开辟空间
cout<<"请输入下一个学生数据,输入所有项为0退出"<<endl;
cout<<"学号:";
cin>>ls->number;
cout<<"姓名:";
cin>>ls->name;
cout<<"数学:";
cin>>ls->shuxue;
cout<<"语文:";
cin>>ls->yuwen;
cout<<"英语:";
cin>>ls->yingyu;
cout<<"物理:";
cin>>ls->wule;
cout<<"化学:";
cin>>ls->huaxue;
}
le->next=NULL;//把链尾指针的next设置为空,因为不管如何循环总是要结束的,设置为空才能够在循环显链表的时候不至于死循环
delete ls;//当结束的时候最后一个动态开辟的内存是无效的,所以必须清除掉
return head;//返回链首指针
}
void showl(test *head)//显示表
{
test * p = head;
//cout<<"链首指针:"<<head<<endl;
while(p)//以内存指向为null为条件循环显示先前输入的内容
{
cout<<p->number<<" "
<<p->name<<" "
<<p->shuxue<<" "
<<p->yuwen<<" "
<<p->yingyu<<" "
<<p->wule<<" "
<<p->huaxue
<<endl;
p=p->next;
}
}
void deletel(test *&head,int number)//(删除)这里如果参数换成test *head,意义就完全不同了,head变成了复制而不是原有链上操作了,特别注意,很多书上都不对这里
{
test *point;//判断链表是否为空
if(head==NULL)
{
cout<<"链表为空,不能进行删除工作!";
return;
}
int derror=1;//设置找不到的情况的条件,预先设置为真
test *check=head;
while(check)//利用循环进行查找
{
if (check->number==number)
{
derror=0;//条件转为假
}
check=check->next;
}
if(derror)//如果为假就跳出函数
{
return;
}
if(head->number==number)//判删除的节点是否为首节点
{
point=head;
cout<<"删除点是链表第一个节点位置!";
head=head->next;//重新设置引导指针
delete point;
return;
}
for(test *mp=head;mp->next;mp=mp->next)
{
if(mp->next->number==number)
{
point=mp->next;
mp->next=point->next;
delete point;
return;
}
}
}
void insterl(int number)//插入
{
test *indata=new test;
cout<<"插入学生成绩"<<endl;
cout<<"学号:";
cin>>indata->number;
cout<<"姓名:";
cin>>indata->name;
cout<<"数学:";
cin>>indata->shuxue;
cout<<"语文:";
cin>>indata->yuwen;
cout<<"英语:";
cin>>indata->yingyu;
cout<<"物理:";
cin>>indata->wule;
cout<<"化学:";
cin>>indata->huaxue;
if(head==NULL)//链表为空的情况下插入
{
head=indata;
indata->next=NULL;
return;
}
int ierror=1;//设置找不到的情况的条件,预先设置为真
test *le;
test *check=head;
while(check)//利用循环进行查找
{
if (check->number==number)
{
ierror=0;//条件转为假
}
le=check;
check=check->next;
}
if(ierror)
{
//cout<<le->number;
le->next=indata;
indata->next=NULL;
return;
}
if(head->number==number)//检测是否是在第一个节点处插入
{
indata->next=head;
head=indata;
return;
}
for(test *mp=head;mp->next;mp=mp->next)//在链表中间插入
{
if(mp->next->number==number)
{
indata->next=mp->next;
mp->next=indata;
return;
}
}
}
void paixu(test *head)//排序
{
test *tmp0=new test;
test *tmp1=head;
while(tmp1)
{
test *tmp2=tmp1->next;
while(tmp2)
{
if(tmp1->zongfen()>tmp2->zongfen())
{
*tmp0=*tmp1;
*tmp1=*tmp2;
*tmp2=*tmp0;
}
tmp2=tmp2->next;
}
tmp1=tmp1->next;
}
delete tmp0;
tmp0 = head;
while(tmp0)
{
cout<<tmp0->number<<" "
<<tmp0->name<<" "
<<tmp0->shuxue<<" "
<<tmp0->yuwen<<" "
<<tmp0->yingyu<<" "
<<tmp0->wule<<" "
<<tmp0->huaxue<<""
<<tmp0->zongfen()<<""
<<tmp0->zongfen()/5.0<<""
<<endl;
tmp0=tmp0->next;
}
}
void main()
{
int mu=1;
int err=1;
while (err!=0)
{
cout<<"\n1--输入学生成绩(学号,姓名,数学,语文,英语,物理,化学)\n"
<<"2--插入学生成绩(学号,姓名,数学,语文,英语,物理,化学)\n"
<<"3--输入学号删除学生成绩\n"
<<"4--按总分排序输出(学号,姓名,数学,语文,英语,物理,化学,总分,平均分)\n"
<<"0--退出\n"
<<"请选择你的操作:";
cin>>mu;
switch(mu)
{
case 1://第一次输入
if(head==NULL)//用来判断是不是第一次输入数据。
{
head=create();//调用创建
showl(head);
err=1;
break;
}
cout<<"您不是第一次输入数据,请选择插入\n\n\n";
break;
case 2://插入数据
showl(head);
int ip;
cout<<"请输入在那个学号前面,如果没有这个学号将在最后插入"<<endl;
cin>>ip;
insterl(ip);
err=1;
break;
case 3://删除数据
showl(head);
int dp;
cout<<"请输入删除点如果找不到就跳出函数"<<endl;
cin>>dp;
deletel(head,dp);//调用删除
err=1;
break;
case 4://排序
if(head!=NULL)
{
paixu(head);
showl(head);
err=1;
break;
}
cout<<"学生成绩数据为空,请输入数据在排序。";
break;
case 0: //退出
err=0;
break;
default://错误
cout<<"输入错误,请重新输入\n";
err=-1;
break;
}
}
}
页:
[1]