/*假设一个链表中包含了一个班级内所有的学生的信息,每个结点含有以下数据域 ?
学号、姓名、各门课成绩以及平均分(假定所有的分数均为0-100的整数),
设计程序用箱排序对指定的成绩排序,并输出排序结果。
基本要求:
(1)每个箱子(0-100)描述成一个链表;
(2)能够从欲排序链表的首部开始,逐个删除每个结点,并把所删除的结点放入适当的箱子中。
(3)收集并链接每个箱子中结点,产生一个排序的链表并输出结果。*/
#include<stdlib.h>
#include<stdio.h>
struct studentnode /*学生信息节点*/
{
char name[10];
char num[19];
int math;
int eng;
int os;
int aver;
struct studentnode * next;
};
typedef struct studentnode studentnode;
typedef struct studentnode * nodelink;
typedef struct boxhead{
studentnode *tail;
}boxnode;
boxnode box[101]; /*箱子组合,每个元素指向一个箱子链表 */
typedef struct head{
studentnode *tail;
}headnode;
headnode head;
int initial(FILE *fp)
{
studentnode *p;
head.tail =NULL;
while(!feof(fp))
{
p=malloc(sizeof(studentnode));
if(fscanf(fp,"%s%s%d%d%d",p->num,p->name,&(p->math),&(p->eng),&(p->os))!=5)
{
printf("文件不完整/n");
exit(0);
}
if(p->eng >100||p->eng <0||p->math >100||p->math <0||p->os >100||p->os <0)
{
printf("文件中的成绩不合法:应该是0——100之间的数字/n");
exit(0);}
p->aver=(p->math+p->eng+p->os)/3;
p->next=head.tail ;head.tail=p;
}
return 1;
}
int inbox(int choose) /*从欲排序链表的首部开始,逐个删除每个结点,并把所删除的结点放入适当的箱子中*/
{
int i;
studentnode *p,* p1;
for(i=0;i<101;i++)
{box[i].tail=NULL;}
switch(choose) /*四种选择的不同处理*/
{
case 1:for(p1=head.tail;p1!=NULL;)
{
p=p1;
p1=p1->next;
p->next=box[p->math].tail;
box[p->math].tail=p; /*逐个更改每个结点的指针,把它挂到相应的箱子中*/
}
break;
case 2: for(p1=head.tail;p1!=NULL;)
{
p=p1;
p1=p1->next;
p->next=box[p->eng].tail;
box[p->eng].tail=p;
}
break;
case 3:for(p1=head.tail;p1!=NULL;)
{
p=p1;
p1=p1->next;
p->next=box[p->os].tail;
box[p->os].tail=p;
}
break;
case 4:for(p1=head.tail;p1!=NULL;)
{
p=p1;
p1=p1->next;
p->next=box[p->aver].tail;
box[p->aver].tail=p;
}
break;
default:printf("你的选择不合法 !/n");break;
}
return 1;
}
int outbox() /*收集并链接每个箱子中结点,产生一个排序的链表并输出结果。*/
{
studentnode *p1,*p;
int i;
head.tail=NULL;
for(i=0;i<101;i++)
{
for(p=box[i].tail;p!=NULL;)
{
p1=p;
p=p->next;
p1->next=head.tail;
head.tail=p1;
}
}
return 1;
}
int main()
{
int choose;char c;
FILE *fp;
studentnode *p;
if((fp=fopen("student.txt","r"))==NULL)
printf("你的数据文件不存在!/n");
else
{
initial(fp);
do{
do{
printf("请输入你要按什么来排序:1:数学 2:英语 3:操作系统 4:平均分/n");
scanf("%d",&choose);
inbox(choose);
}while(choose<0||choose>4);
outbox();
printf("按你的要求箱排序后的排名如下(从高到低) :/n");
printf("学号 /t姓名/t数学/t英语/t操作系统/t平均分/n");
for(p=head.tail;p!=NULL;p=p->next)
printf("%s /t%s /t%d /t%d /t%d /t%d/n",p->num,p->name,p->math,p->eng,p->os,p->aver);
printf("继续查询请按y或Y/n退出请按任意键:");
getchar();
scanf("%c",&c);
}while(c=='y'||c=='Y');
}
}