之前遇到排序只会想到如冒泡,选择,快速排序等等,刚刚跟学到了用结构体的方法来排序,针对类似成绩排序题还行。
头文件:
#include<stdlib.h> #include<string.h>
定义结构体:
1 typedef struct Stu{ 2 char name[10]; 3 int id; 4 int score; 5 }stu;/*stu是别名*/
定义排序(回调)函数:
1 /*定义排序函数*/ 2 int cmp(const void *a,const void *b){ 3 stu c = *(stu*)a; 4 stu d = *(stu*)b; 5 //printf("%d ",strcmp(c.name,d.name)); 6 /*返回值是0、1*/ 7 if(strcmp(c.name,d.name)>0){ 8 return strcmp(c.name,d.name); 9 } 10 else{ 11 if(strcmp(c.name,d.name)==0){ 12 return c.id-d.id; 13 } 14 } 15 }
或者:
int cmp(const void *c,const void *d){
return *(int *)c - *(int *)d;
}
使用qsort函数:
qsort(st,n,sizeof(st[0]),cmp);
头文件:stdlib.h
用 法: void qsort( void *base,int nelem,int width,int ( *fcmp)( const void *,const void * ));
参数列表:
- 待排序数组首地址;
- 数组中待排序元素数量;
- 单个元素的大小,推荐使用sizeof(st[0])这样的表达式;
- 指向函数的指针,用于确定排序的顺序.
下面是一个成绩排序程序的代码:
代码一:非结构体排序方法:
1 #include<stdio.h> 2 #include<string.h> 3 int main() 4 { 5 int n; 6 char name[20]; 7 char sex[20]; 8 char year[20]; 9 int score[200]; 10 11 int max = -1; 12 int mix = 200; 13 /*最高分者信息*/ 14 char maxname[20]; 15 char maxsex[20]; 16 char maxyear[20]; 17 /*最低分者信息*/ 18 char mixname[20]; 19 char mixsex[20]; 20 char mixyear[20]; 21 22 scanf("%d",&n); 23 for(int i=0;i<n;i++){ 24 scanf("%s",name); 25 scanf("%s",sex); 26 scanf("%s",year); 27 scanf("%d",&score[i]); 28 /*若当前输入的分数比mix小,则将此条信息记录为最低分者*/ 29 if(score[i]<mix){ 30 strcpy(mixname,name); 31 strcpy(mixsex,sex); 32 strcpy(mixyear,year); 33 mix = score[i]; 34 } 35 /*若当前输入的分数比max大,则将此条信息记录为最高分者*/ 36 if(score[i]>max){ 37 strcpy(maxname,name); 38 strcpy(maxsex,sex); 39 strcpy(maxyear,year); 40 max = score[i]; 41 } 42 } 43 printf(" 最高者:%s 性别:%s 年龄:%s ",maxname,maxsex,maxyear); 44 printf("最低者:%s 性别:%s 年龄:%s ",mixname,mixsex,mixyear); 45 }
代码二:结构体排序:
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #include<math.h> 5 #include<ctype.h> 6 /*定义一个结构体*/ 7 typedef struct Stu{ 8 char name[100]; 9 char sex[10]; 10 int age; 11 int score; 12 }stu; 13 /* 定义排序(回调)函数cmp: 14 返回类型必须是int; 15 两个参数的类型必须都是const void *; 16 如果是升序,那么就是如果a比b大返回一个正值,小则负值,相等返回0; 17 */ 18 int cmp(const void *a,const void *b){ 19 /* *(stu*)a是因为:a是个void *类型,要先 20 用(stu*)将它转成stu*类型,然后再用*取值, 21 变成stu类型,才能比较大小。*/ 22 stu c=*(stu*)a; 23 stu d=*(stu*)b; 24 //按成绩升序排序 25 return c.score-d.score; 26 } 27 main(){ 28 int n; 29 stu sz[100]; 30 scanf("%d",&n); 31 for(int i=0;i<n;i++){ 32 scanf("%s %s %d %d",&sz[i].name,&sz[i].sex,&sz[i].age,&sz[i].score); 33 } 34 /* 35 qsort函数参数: 36 1 待排序数组首地址; 37 2 数组中待排序元素数量; 38 3 各元素的占用空间大小,推荐使用sizeof(s[0])这样,特别是对结构体 ; 39 4 指向函数的指针,用于确定排序的顺序. 40 注意:如果要对数组进行部分排序,比如对一个s[n]的数组排列其从s[i]开始的m个元素,只需要 41 在第一个和第二个参数上进行一些修改:qsort(&s[i],m,sizeof(s[i]),cmp); 42 */ 43 qsort(sz,n,sizeof(sz[0]),cmp); 44 printf(" 按成绩升序为: "); 45 for(int i=0;i<n;i++){ 46 printf("%s %s %d %d ",sz[i].name,sz[i].sex,sz[i].age,sz[i].score); 47 } 48 }