给出n个学生的考试成绩表,每条记录由学号、姓名和分数和名次组成,设计算法完成下列操作:
(1)设计一个显示对学生信息操作的菜单函数如下所示:
*************************
1、录入学生基本信息
2、直接插入排序
3、冒泡排序
4、快速排序
5、简单选择排序
6、堆排序
7、2-路归并排序
8、输出学生信息
0、退出
*************************
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 20 //学生最多人数
typedef struct{
char num[20]; //学号
char name[20]; //姓名
int score; //分数
}stu;
typedef struct{
stu R[MAXSIZE+1]; //0单元作为监视哨
int length;
}Sqlist;
void menu(){
printf("**************************\n");
printf("\t1. 录入学生基本信息\n");
printf("\t2. 直接插入排序\n");
printf("\t3. 冒泡排序\n");
printf("\t4. 快速排序\n");
printf("\t5. 简单选择排序\n");
printf("\t6. 堆排序\n");
printf("\t7. 2-路归并排序\n");
printf("\t8. 输出学生信息\n");
printf("\t0. 退出\n");
printf("**************************\n");
printf("请选择:\n");
}
void InputInformation(Sqlist &L){
int i;
FILE *fp;
if((fp=fopen("stdinf.txt","w"))==NULL){
printf("无法打开该文件!\n");
return ;
}
printf("请输入学生人数:");
scanf("%d",&L.length);
printf("请输入学生的学号,姓名,分数\n");
for(i=1;i<=L.length;i++){
scanf("%s%s%d",L.R[i].num,L.R[i].name,&L.R[i].score);
fprintf(fp,"%8s%8s%8d\n",L.R[i].num,L.R[i].name,L.R[i].score);
}//while
fclose(fp);
}
void Readfile(Sqlist L){
FILE *fp;
int i;
fp = fopen("stdinf.txt","r");
for(i=1;i<=L.length;i++)
fscanf(fp,"%s %s %d\n",L.R[i].num,L.R[i].name,&L.R[i].score);
fclose(fp);
}
void InsertSort(Sqlist &L){
int i,j;
for(i=2;i<=L.length;i++)
if(L.R[i].score > L.R[i-1].score){
L.R[0] = L.R[i]; //R[i]为哨兵
L.R[i] = L.R[i-1];
for(j=i-2;L.R[0].score >L.R[j].score;j--)
L.R[j+1] = L.R[j];
L.R[j+1] = L.R[0];
}//if
}
void BubbleSort(Sqlist &L){
int flag=1,i,j;
for(i=1;i<=L.length && flag;i++){
flag = 0;
for(j=1;j<=L.length-i;j++)
if(L.R[j].score < L.R[j+1].score){
L.R[0] = L.R[j]; L.R[j] = L.R[j+1];
L.R[j+1] = L.R[0]; flag = 1;
}//if
}//for
}
int Partition(Sqlist &L,int low,int high){
int pivotscore = L.R[low].score;
L.R[0] = L.R[low];
while(low<high){
while(low<high && L.R[high].score <= pivotscore)
high--;
if(low<high)
L.R[low++] = L.R[high];
while(low<high && L.R[low].score >= pivotscore)
low++;
if(low<high)
L.R[high--] = L.R[low];
}//while
L.R[low] = L.R[0];
return low;
}
void QSort(Sqlist &L,int low,int high){
int pivotloc;
if(low<high){
pivotloc=Partition(L,low,high);
QSort(L,low,pivotloc-1);
QSort(L,pivotloc+1,high);
}
}
void QuickSort(Sqlist &L){
QSort(L,1,L.length);
}
void SelectSort(Sqlist &L){
int i,j,k;
for(i=1;i<L.length;i++){
k = i;
for(j=i+1;j<=L.length;j++)
if(L.R[k].score < L.R[j].score )
k = j;
if(i!=k){
L.R[0] = L.R[k]; L.R[k] = L.R[i]; L.R[i] = L.R[0];
}//if
}//for
}
void HeapAdjust(Sqlist &L,int s,int m){
int j;
L.R[0] = L.R[s];
for(j=2*s;j<=m;j*=2){
if(j<m && L.R[j].score > L.R[j+1].score) //沿k较小的结点向下筛选
j++; //j为score较小记录的下标
if(L.R[0].score <= L.R[j].score )
break;
L.R[s] = L.R[j]; s=j;
}//for
L.R[s] = L.R[0]; //插入
}
void HeapSort(Sqlist &L){
int i,t;
for(i=L.length/2;i>0;i--) //建立初始堆
HeapAdjust(L,i,L.length);
for(i=L.length;i>1;i--){
t = L.R[1].score; L.R[1].score = L.R[i].score; L.R[i].score = t;
HeapAdjust(L,1,i-1);
}
}
void Merge(Sqlist &L,int s,int m,int n){
int i,j,k;
Sqlist T;
i=s; j=m+1; k=0;
while(i<=m && j<=n) //归并两个相邻的有序表
if(L.R[i].score>=L.R[j].score)
T.R[k++] = L.R[i++];
else
T.R[k++] = L.R[j++];
while(i<=m)
T.R[k++] = L.R[i++];
while(j<=n)
T.R[k++] = L.R[j++];
for(i=s;i<=n;i++) //将T表中的元素复制到表L中
L.R[i] = T.R[i-s];
}
void MSort(Sqlist &L,int low,int high){
int mid;
if(low<high){
mid=(low+high)/2;
MSort(L,low,mid);
MSort(L,mid+1,high);
Merge(L,low,mid,high);
}
}
void MergeSort(Sqlist &L){
MSort(L,1,L.length);
}
void show(Sqlist L){
int i;
int rank=1,index=0;
FILE *fp;
if((fp=fopen("stdinf.dat","w"))==NULL){
printf("无法打开该文件!\n");
return ;
}
printf("输出排名后所有学生的信息\n");
printf(" 名次 姓名 学号 分数\n");
for(i=1;i<=L.length;i++){
printf("%6d%8s%7s%7d\n",rank,L.R[i].name,L.R[i].num,L.R[i].score);
if(i<L.length && L.R[i].score==L.R[i+1].score)
index++;
else{
rank+=index+1;
index=0;
}//else
}
fclose(fp);
}
int main(){
Sqlist L;
int choice;
while(1){
menu();
scanf("%d",&choice);
switch(choice){
case 1: InputInformation(L);break;
case 2: Readfile(L); InsertSort(L);break;
case 3: Readfile(L); BubbleSort(L);break;
case 4: Readfile(L); QuickSort(L);break;
case 5: Readfile(L); SelectSort(L);break;
case 6: Readfile(L); HeapSort(L);break;
case 7: Readfile(L); MergeSort(L);break;
case 8: Readfile(L); show(L);break;
case 0: return 0;
default:printf("\n\t输入错误,请重新选择!\n");
}//switch
}//while
}