我们在实际应用中的排序可能会不止一种,这时我们可能会在之前的基础上,进行进一步的比较,说白了,也就是多级排序。
如何能实现自己的多级排序呢?如何能够利用泛型的思想,相对什么数据进行排序就可以对什么数据进行排序,在写今天这篇博客之前,我们虽然都接触过函数指针,但很少去使用,也许是在学校根本涉及不到,因此,我们并不能知道其强大的功能。
最近看到这样一个题,要求从文件中读取一个学生的结构体,在成绩的基础上,女生优先,在同样性别的情况下,身高高的优先。这就好比在面试过程中(虽然我还没有面临这个问题,但马上会面对),如果在笔试或者面试成绩相同情况下,这时候公司会考虑其他的情况,比如学历,性别,出生地等各种信息。这就引出了多级排序的思想,当然你也可以确定数据类型,然后写多个不同的排序来完成这个功能。但数据类型变了呢,你的代码又要被改动。因此,我们要尽可能写出泛型的代码。好了,废话不多说了,其实,当我的代码写完时,发现其实C语言函数库其实为我们提供了这个功能,qsort()函数,大家有兴趣可以去看看。不过在写代码的过程中还是学习到了很多东西。大家可能等不及了,上代码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student;
int cmp_score(void *,void *);
int cmp_sex(void *,void *);
int cmp_height(void *,void *);
void write(struct student *s,int len,char *path);
void read(struct student *s,int len,char *path);
void any_sort(void* s,int size,int nu,int (*cmp)(void*,void*));
struct student
{
char name[10];
short age;
short score;
short height;
char sex[6];
};
int main(int argc,char *argv[])
{
if(argc!=2)
{
printf("canshubuzu\n");
return -1;
}
int i =0;
struct student s[7]=
{{"abc",23,60,160,"men"},{"ade",23,60,160,"women"},
{"adf",23,60,165,"women"},{"asdf",24,67,166,"men"},{"sfs",23,68,156,"men"},
{"def",25,78,165,"women"},{"sfw",24,35,178,"men"}};
struct student s1[7];
write(s,7,argv[1]);
read(s1,7,argv[1]);
any_sort((void*)s,sizeof(struct student),7,cmp_score);
for(i = 0;i<7;i++)
{
printf("%s %d %d %d %s\n",s[i].name,s[i].age,s[i].score,s[i].height,s
[i].sex);
}
return 0;
}
void read(struct student *s,int len,char *path)
{
FILE *fp = NULL;
int i = 0;
fp = fopen(path,"rb");
if(NULL == fp)
{
perror("fopen fail\n");
return;
}
while(i<len)
{
fread(s+i,sizeof(struct student),1,fp);
i++;
}
fclose(fp);
}
void write(struct student *s,int len,char *path)
{
int i =0;
FILE *fp = NULL;
fp = fopen(path,"wb");
if(NULL == fp)
{
return;
}
while(i<len)
{
fwrite(s+i,sizeof(struct student),1,fp);
i++;
}
fclose(fp);
}
void any_sort(void* s,int size,int nu,int (*cmp)(void*,void*))
{
int i,j;
void* buf=malloc(size);
int index;
if(NULL == buf)
{
return;
}
for(i = 0;i<nu-1;i++)
{
index = i;
for(j =i;j<nu;j++)
{
if(cmp((void*)((char*)s+index*size),(void*)((char*)s+j*size))>0)
index = j;
}
if(i!=index)
{
memcpy(buf,(void*)((char*)s+i*size),size);
memcpy((void*)((char*)s+i*size),(void*)((char*)s+index*size),size);
memcpy((void*)((char*)s+index*size),buf,size);
}
}
free(buf);
}
int cmp_score(void *a,void *b)
{
struct student s1 = *(struct student*)a;
struct student s2 = *(struct student*)b;
if(s1.score == s2.score)
{
if(0 == cmp_sex(a,b))
{
return cmp_height(a,b);
}
else
return cmp_sex(a,b);
}
return s1.score-s2.score;
}
int cmp_sex(void *a,void *b)
{
struct student s1 =*(struct student*)a;
struct student s2 =*(struct student*)b;
return -strcmp(s1.sex,s2.sex);
}
int cmp_height(void *a,void *b)
{
struct student s1 = *(struct student*)a;
struct student s2 = *(struct student*)b;
return s2.height-s1.height;
}
运行结果: