第一篇:
C语言实现成绩的:直接插入排序、选择排序、希尔排序
刚好在学数据结构,想着把自己完成的一些代码发出来,缺陷自然是多多啦,所以希望大家能多多指教!!!
CSDN没用多久,markdown也是第一次用,很蒙圈,本来还想详细解释一下算法什么的,但排版什么的实在是难为我,等什么时候用空再研究研究这些吧!!!
问题描述:
给出n个学生的考试成绩表,每条信息由姓名和分数组成:
- 按分数高低次序,打印出每个学生在考试中获得的名次,分数相同的为同一名次;
- 按名次列出每个学生的姓名与分数
- 给出直接插入排序、选择排序、希尔排序三种排序方式
代码如下
#include <stdio.h>
#include <stdlib.h>
typedef struct Student{
char name[20];
int score;
}Student,*ST;
int number = 0; //学生数量
void shuruxinxi(ST &stu){
printf("\n--------------------请输入学生信息------------------");
for(int k = 0; k < number; k++){
printf("\n&&第%d位学生\n",k+1);
printf("姓名:");
scanf("%s",stu[k].name);
printf("成绩:");
scanf("%d",&stu[k].score);
printf("\n###########################\n");
}
}
//直接插入排序
ST ChaRuPaiXu(ST stu,int number1){
ST p = (ST)malloc((number1 + 1)*sizeof(Student));
for(int m = 1;m<=number1;m++){
p[m]=stu[m-1];
}
for(int i = 2;i<=number1;i++){
int kk = i;
p[0] = p[i];
for(int j = i-1;p[0].score>p[j].score;j--){
p[kk] = p[j];
p[j] = p[0];
kk = j;
}
}
return p+1;
}
//选择排序
ST XuanZe(ST stu){
ST p = (ST)malloc((number)*sizeof(Student));
ST guoDu = (ST)malloc(sizeof(Student));
int maxScore;
for(int m = 0;m<number;m++){
p[m]=stu[m];
}
for(int i = 0;i<number;i++){
int k = i;
maxScore = p[i].score;
for(int j = i+1;j<number;j++){
if(maxScore < p[j].score){
maxScore = p[j].score;
k = j;
}
}
guoDu[0] = p[i];
p[i]=p[k];
p[k] = guoDu[0];
}
return p;
}
//希尔排序
ST XiErPaiXu(ST stu){
ST VirtaulStu;
ST stu1 = (ST)malloc(number*sizeof(Student));
for(int num = 0;num<number;num++){
stu1[num] = stu[num];
}
for(int d = number/2;d>=1;d=d/2){
int n = 0,max;
n = (number-1)/d; //n+1后代表一次最多可以读多少个,例如number=8,d=3时一次最多可以从stu[]数组中读3个数:1 4 7或2 5 8
if(number%(1+n)){ //如果取余之后不等于0代表还需要在多读一次,接上例还有3, 6没读
max = number/(1+n) + 1; //max表示到第max个数后+d+d...就能读完,接上例到3可以读完可以分为1 4 7、2 5 8、3 6读完整个数组
}else {
max = number/(1+n); //若取模不等于0意味着每次读n+1个,可以刚好读完整个数组,例如number=8,d=4,则每次读2个,可刚好读完:1 5、2 6、3 7、4 8
}
for(int i = 1;i<=max;i++){
VirtaulStu = (ST)malloc(((number-i)/d + 1)*sizeof(Student));
for(int j = 0;j<(number-i)/d + 1;j++){
VirtaulStu[j] = stu1[i-1+d*j];
}
VirtaulStu = ChaRuPaiXu(VirtaulStu,((number-i)/d + 1));
for(int j1 = 0;j1<(number-i)/d + 1;j1++){
stu1[i-1+d*j1] = VirtaulStu[j1];
}
}
}
return stu1;
}
//输出排名
void OutPut(ST p){
int mingci;
for(int z = 0;z<number;z++){
if(z == 0 || p[z].score<p[z-1].score){
mingci = z +1;
}
printf("第%d名:姓名:%s\t成绩:%d\n",mingci,p[z].name,p[z].score);
}
}
//菜单
void meau(){
printf("\t\t\t&&&&&&&&&&&&&&&&&&&&&&&||学生信息查找||&&&&&&&&&&&&&&&&&&&&&\n");
printf("\t\t\t& A.输入学生数、姓名及成绩 &\n");
printf("\t\t\t& B.用直接插入排序输出名次 &\n");
printf("\t\t\t& C.用选择排序输出名次 &\n");
printf("\t\t\t& D.用希尔排序输出名次 &\n");
printf("\t\t\t& E.退出 &\n");
printf("\t\t\t&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n");
}
void main(){
ST stu;
int Assure;
while(Assure){
char choose;
meau();
printf("请输入选项:");
scanf("%c",&choose);getchar();
switch(choose){
case 'a':
case 'A':
printf("请输入学生总数:\t");
scanf("%d",&number);
stu = (ST)malloc(number*sizeof(Student));
shuruxinxi(stu);
break;
case 'b':
case 'B': //直接插入排序
if(number>1){
OutPut(ChaRuPaiXu(stu,number));
}else{
printf("第1名:姓名:%s\t成绩:%d\n",stu[0].name,stu[0].score);
}
break;
case 'c':
case 'C': //选择排序
OutPut(XuanZe(stu));
break;
case 'd':
case 'D': //希尔排序
OutPut(XiErPaiXu(stu));
//XiErPaiXu(stu);
break;
case 'e':
case 'E': //退出
exit(0);
default:
printf("输入错误!!!\n");
}
printf("\n是否继续: 是/1 否/0\t");
scanf("%d",&Assure);
getchar(); //消除enter符
printf("\n");
system("cls");
}
}
效果如下:
直解插入排序
选择排序
后面的自然也是这样,就不放效果图了,还有一些代码可以简化,一些空间的开辟之类的不太好,之后再改进吧!!!