C语言基础-利用回调函数机制写万能排序函数

利用回调函数机制写万能排序函数

手写万能排序的思路:

假设自定义万能排序的函数名为:MyQSort

  1. 使用冒泡排序;
  2. 确定形参:
    1)因为不知道传入到MyQSort中的是那种类型的数组,所以使用void* 无类型指针类型用于接收数组的首地址。
    2)因为接收的是数组首地址,也不知道数组元素的数据类型,所需需要“数组的大小”和“数组元素的大小”
    3)需传入一个比较器。能做到万能排序的原因,这是关键点。一种数据类型对应着一个比较器,用于比较两数组元素的大小,用于排序。
  3. 因为接收是数组的首元素地址,而且不知道数据类型。
    1)换个思路来想,可以使用char类型的指针,获取每个元素的首地址,再加上指定的元素大小,就可以知道该数组元素在内存中的地址范围。
    2)因此,就可以拿到该元素的所有数据,传入比较器后,将void
    类型强转所需类型即可正常比较。
  4. 然后根据冒泡排序的思想,如果前一个数组元素大于后一个,两个元素进行交换即可。
#define  _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct People{

	char name[20];
	short age;


};
//交换两元素的内容。
//这里直接将实参(void*)强转成了char*,便于使用
void Swap(char*e1, char* e2, int weight){
	int i = 0;
	for (i = 0; i < weight; i++){

		char temp = *(e1+i);
		*(e1 + i) = *(e2 + i);
		*(e2 + i) = temp;

	}




}


//万能冒泡排序:
//data : 可以接收各种类型的数组
//size : 数组的元素个数
//weight :	每个元素的大小(相当于sizeof(arr[0])的大小
//cmp  : 自定义比较大小的函数
void MyQSort(void* data, int size, int weight, int(*cmp)(const void* e1, const void * e2)){

	//利用冒排序进行排序:
	int i = 0;
	for ( i = 0; i < size-1; i++)
	{
		int j = 0;
		for (j = 0; j < size-i - 1; j++){
			//以字节为单位,传递数组的每个首元素地址。然后根据元素的整体大小移步指针。
			if (cmp(((char*)data + j*weight), ((char*)data + (j + 1)*weight)) > 0){
				//交换两元素
				Swap(((char*)data + j*weight), ((char*)data + (j + 1)*weight), weight);
			}

		}


	}




}
//自定义比较器
int Mycmp_age(const void* e1, const void * e2){

	struct People* a1 = (struct People *)e1;

	struct People* a2 = (struct People *)e2;

	return (a2->age) - (a1->age);


}

//打印函数
void Printfs(const struct People* arr,int size){
	int i = 0;
	for (i = 0; i < size; i++){
		printf("name : %s\t age : %d\n", arr->name, arr->age);
		arr++;
	}
}
/*


*/
int main(){
	
	struct People arr[] = { { "zhangsan", 20 }, { "lisi", 12 }, { "wanger", 22 }, {"mazi",16} };
	//数组大小
	int size = sizeof(arr) / sizeof(arr[0]);
	//手写万能冒泡排序:
	MyQSort(arr, size, sizeof(arr[0]), Mycmp_age);
	//打印
	Printfs(arr, size);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值