利用函数指针实现多级排序

我们在实际应用中的排序可能会不止一种,这时我们可能会在之前的基础上,进行进一步的比较,说白了,也就是多级排序。

如何能实现自己的多级排序呢?如何能够利用泛型的思想,相对什么数据进行排序就可以对什么数据进行排序,在写今天这篇博客之前,我们虽然都接触过函数指针,但很少去使用,也许是在学校根本涉及不到,因此,我们并不能知道其强大的功能。

最近看到这样一个题,要求从文件中读取一个学生的结构体,在成绩的基础上,女生优先,在同样性别的情况下,身高高的优先。这就好比在面试过程中(虽然我还没有面临这个问题,但马上会面对),如果在笔试或者面试成绩相同情况下,这时候公司会考虑其他的情况,比如学历,性别,出生地等各种信息。这就引出了多级排序的思想,当然你也可以确定数据类型,然后写多个不同的排序来完成这个功能。但数据类型变了呢,你的代码又要被改动。因此,我们要尽可能写出泛型的代码。好了,废话不多说了,其实,当我的代码写完时,发现其实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;

}

运行结果:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值