题目:
统计成绩,给出n个学生的考试成绩表,每条信息由学号、姓名与分数组成。要求:
(1)首先按学号排序;
(2)再按分数排序,并要求分数相同的仍然保持按学号有序。
1.数据分析
成绩表中数据:学号,姓名,成绩
首先依次按照输入顺序将学号,姓名,成绩放置在顺序表中存放。
2.主要算法分析
(1)将顺序表中数据依次取出,运用冒泡法进行对比。若前者学号大于后者学号,则二者交换位置,直到学号按照从小到大顺序依次排列整齐为止。
(2)将顺序表中数据依次取出,运用冒泡法进行对比。若前者成绩小于后者成绩,则二者交换位置,直到成绩按照从大到小顺序依次排列整齐为止且相同成绩仍保持学号有序。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_SIZE 50
#define MAX_LEN 20 //姓名长度不超过20个字符
typedef struct {int st;}STType; //学号
typedef struct { char name[MAX_SIZE][MAX_LEN];}NameType; //假设姓名最多输入MAX_SIZE个中文姓名,每个姓名长度不超过MAX_LEN个字符
typedef struct {int score;}ScoreType; //分数
//定义顺序表结构体
typedef struct{
STType Number[MAX_SIZE];
NameType Name[MAX_SIZE];
ScoreType Score[MAX_SIZE];
}SeqList;
//创建顺序表
void CreatList(SeqList *L){
int i,cnt;
int num,cj;
printf("请输入您要创建的学生信息人数:");
scanf("%d",&cnt);
printf("请依次输入学号:\n");
for(i=0;i<cnt;i++){
scanf("%d",&num);
L->Number[i].st=num;
}
printf("请依次输入姓名:\n");
for(i=0;i<cnt;i++){
scanf("%s",L->Name[i].name[i]);
}
printf("请依次输入成绩:\n");
for(i=0;i<cnt;i++){
scanf("%d",&cj);
L->Score[i].score=cj;
}
}
//按照学号排序,cnt是存放进表里的总数,cnt是存放进表里的总数
void ST(SeqList *L,int cnt){
int i,j;
int mid;
char names[MAX_LEN];
for(i=0;i<cnt-1;i++){
for(j=i+1;j<=cnt-1;j++){
if(L->Number[i].st>L->Number[j].st){
//交换学号
mid=L->Number[j].st;
L->Number[j].st=L->Number[i].st;
L->Number[i].st=mid;
//交换姓名
memcpy(names, L->Name[i].name[i], sizeof(L->Name[i].name[i]));
memcpy(L->Name[i].name[i], L->Name[j].name[j], sizeof(L->Name[j].name[j]));
memcpy(L->Name[j].name[j], names, sizeof(names));
//交换成绩
mid=L->Score[j].score;
L->Score[j].score=L->Score[i].score;
L->Score[i].score=mid;
}
}
}
}
//按照成绩排序,且分数相同的同学按照学号从小到大进行排序,cnt是存放进表里的总数
void Score(SeqList *L,int cnt){
int i,j;
int mid;
char names[MAX_LEN];
for(i=0;i<cnt-1;i++){
for(j=i+1;j<=cnt-1;j++){
if(L->Score[i].score<L->Score[j].score){
//交换成绩
mid=L->Score[j].score;
L->Score[j].score=L->Score[i].score;
L->Score[i].score=mid;
//交换姓名
memcpy(names, L->Name[i].name[i], sizeof(L->Name[i].name[i]));
memcpy(L->Name[i].name[i], L->Name[j].name[j], sizeof(L->Name[j].name[j]));
memcpy(L->Name[j].name[j], names, sizeof(names));
//交换学号
mid=L->Number[j].st;
L->Number[j].st=L->Number[i].st;
L->Number[i].st=mid;
}
}
}
//上述已经将成绩表按照分数从大到小排序,下边进行分数相同按照学号从小到大排序
//因为成绩相同,所以不需要再移动成绩,只需要移动学号和姓名即可
for(i=0;i<cnt-1;i++){
for(j=i+1;j<=cnt+1;j++){
if(L->Score[i].score==L->Score[j].score){
if(L->Number[i].st>L->Number[j].st){
//交换学号
mid=L->Number[j].st;
L->Number[j].st=L->Number[i].st;
L->Number[i].st=mid;
//交换姓名
memcpy(names, L->Name[i].name[i], sizeof(L->Name[i].name[i]));
memcpy(L->Name[i].name[i], L->Name[j].name[j], sizeof(L->Name[j].name[j]));
memcpy(L->Name[j].name[j], names, sizeof(names));
}
}
}
}
}
//遍历顺序表
void TravelList(SeqList *L,int cnt){
int i;
printf("学生考试表:\n");
printf("学号 姓名 成绩\n");
for(i=0;i<=cnt-1;i++){
printf(" %d %s %d\n",L->Number[i].st,L->Name[i].name[i],L->Score[i].score);
}
}
int main(){
SeqList L;
CreatList(&L);
ST(&L,5);
Score(&L,5);
TravelList(&L,5);
system("pause");
return 0;
}
问题(1):
问题(2):
如果两个分数相同,则按照学号由小到大排序。