问题描述
设计相应的单链表类型数组,完成一个班学生的学号、姓名、语文成绩、数学成绩、外语成绩的输入;计算每位同学的总分及平均分,并按表格形式输出学生的所有信息;将上述表格按照学生的平均分排序。
问题分析
拆分问题为:
(1)声明结构体struct Transcript,struct Node(链表节点);
(2)构建函数LinkList CreateFromTail()(或LinkList CreateFromTail())建立链表;
(3)构建函数void order(LinkList L),对链表排序;
(4)构建函数void Traver(LinkList p),遍历并输出链表;
(5)构建函数void DesList(LinkList L),实放链表内存;
代码
#include<iostream>
using namespace std;
struct Transcript
{
char sNum[20];
char name[10];
double cScore;
double mScore;
double eScore;
double sum;
double averange;
};
struct Node
{
Transcript tran;
Node *next;
};
typedef Node* LinkList;
LinkList CreateFromHead()// 头插法建表
{
LinkList L;// 头指针
Node *s;
int flag=1;
Transcript x;
L=new Node;// 为头节点分配存储空间
L->next=NULL;// 头节点指向空指针
while(flag)
{
puts("Please enter the school number:");
cin>>x.sNum;
puts("Please enter the name:");
cin>>x.name;
puts("Please enter the Chinese score:");
cin>>x.cScore;
puts("Please enter the Math score:");
cin>>x.mScore;
puts("Please enter the English score:");
cin>>x.eScore;
x.sum=x.cScore+x.eScore+x.mScore;
x.averange=x.sum/3;
s=new Node;// 为新节点分配存储空间
s->tran=x;// 为新节点数据域赋值
s->next=L->next;// 插入新指针
L->next=s;
puts("next?(1/0)");// 判断是否继续输入数据
cin>>flag;
}
return L;
}
LinkList CreateFromTail()// 尾插法建表 // 未使用
{
LinkList L;// 头指针
Node *r,*s;
int flag=1;
Transcript x;
L=new Node;// 为头节点分配存储空间
L->next=NULL;
r=L;// r指针始终动态指向链表当前表尾结点
while(flag)
{
puts("Please enter the school number:");
cin>>x.sNum;
puts("Please enter the name:");
cin>>x.name;
puts("Please enter the Chinese score:");
cin>>x.cScore;
puts("Please enter the Math score:");
cin>>x.mScore;
puts("Please enter the English score:");
cin>>x.eScore;
x.sum=x.cScore+x.eScore+x.mScore;
x.averange=x.sum/3;
s=new Node;// 为新节点分配存储空间
s->tran=x;// 为新节点数据域赋值
r->next=s;// 插入新节点
r=s;
r->next=NULL;// 尾节点指向空指针
puts("Next?(1/0)");
cin>>flag;
}
return L;
}
int InsList(LinkList L,int i,Transcript e)// 插入节点 // 未使用
{
int k=0;
Node *pre=L,*s;
while(pre!=NULL && k<i-1)// 搜索第i-1个节点,并保证第i-2个节点不为尾节点
{
pre=pre->next;
k++;
}
if(pre==NULL)
{
puts("Unreasonable insertion!");
return 0;
}
s=new Node;// 为新节点分配存储空间
s->tran=e;// 为新节点数据域赋值
s->next=pre->next;// 插入新节点
pre->next=s;
return 1;
}
int DelList(LinkList L,int i,Transcript *e)// 删除节点 // 未使用
{
int k=0;
Node *pre=L,*r;
while(pre->next!=NULL && k<i-1)// 搜索第i-1个节点,并保证第i-1个节点不为尾节点
{
pre=pre->next;
k++;
}
if(pre->next==NULL)
{
puts("Unreasonable deletion!");
return 0;
}
*e=pre->next->tran;
r=pre->next;// 删除r节点
pre->next=r->next;
delete r;// 释放被删除的r节点的内存空间
return 1;
}
void Traver(LinkList p)// 遍历并输出链表
{
Node *s;
s=p->next;
while(s)
{
cout<<s->tran.sNum<<"\t"<<s->tran.name<<"\t"<<s->tran.cScore<<"\t"<<s->tran.mScore<<"\t"<<s->tran.eScore<<"\t"<<s->tran.sum<<"\t"<<s->tran.averange<<endl;
s=s->next;
}
}
void DesList(LinkList L)// 释放链表内存
{
Node *s=L,*r;
r=s->next;
while(r)
{
delete s;
s=r;
r=s->next;
}
delete s;
}
void order(LinkList L)// 链表排序 // 选择排序
{
Node *p,*q,*t;
Transcript x;
for(p=L->next;p->next!=NULL;p=p->next)// 设置比较趟数 // 遍历至倒数第二个节点
{
t=p;
for(q=t->next;q!=NULL;q=q->next)// 搜索每趟中最大值 // 遍历至尾节点
{
if(t->tran.averange<q->tran.averange) t=q;
}
if(t!=p)// 交换数据域
{
x=p->tran;
p->tran=t->tran;
t->tran=x;
}
}
}
int main()
{
LinkList p;//头指针
p=CreateFromTail();// 建表
order(p);// 排序
Traver(p);// 遍历并输出
DesList(p);// 释放内存
return 0;
}