回调函数(函数指针做函数参数)
本函数底层排序算法使用选择排序,实现对任意数组类型进行排序。
qsort的函数原型,参数1,数组的首地址;参数2,数组的长度;参数3,数组中每个元素的大小;参数4,回调函数,用户提供比较规则;
void qsort(void *base,size_t num,size_t len,int(*compare)(const void *,const void*));
自定义函数实现qsort功能。以往选择排序需要找出数组中的最小值或者最大值,需要定义一个max或者是min,而此算法避免了在函数内部把排序规则写死,从大到小还是从小到大都由用户说了算,用户只需提供一个回调函数指明规则即可。
1 //选择排序 2 void MySort(void *data,int len,int elesize, 3 int (*mycompara)(void *,void *)) 4 { 5 char *pAddr = data; 6 int MinOrMax; 7 char *tmp = (char *)malloc(elesize); 8 for (size_t i = 0; i < len-1; i++) 9 { 10 MinOrMax = i; 11 for (int j = i + 1; j < len; j++) 12 { 13 //j元素地址 14 char *pj = pAddr + elesize*j; 15 //最大或最小值的地址 16 char *pminormax = pAddr + elesize*MinOrMax; 17 if (mycompara(pj,pminormax)) 18 //到底是从大到小排序还是从小到大排序由用户说了算 19 //用户来提供比较的规则 20 MinOrMax = j; 21 } 22 if (MinOrMax != i) 23 { 24 //i元素的地址 25 char *pi = (char *)pAddr + elesize*i; 26 //最小值或最大值地址 27 char *pminormax = (char *)pAddr + elesize*MinOrMax; 28 //交换 29 memcpy(tmp, pi, elesize); 30 memcpy(pi, pminormax, elesize); 31 memcpy(pminormax, tmp, elesize); 32 33 } 34 } 35 //记得释放 36 if (tmp != NULL) 37 { 38 free(tmp); 39 tmp = NULL; 40 } 41 }
用户自己提供的回调函数,如果是自定义数据类型,需要指明是按id从小到大排序,还是从大到小排序。当然也可以按其他可比较的字段进行排序。
int mycomparaperson(void *arg1, void *arg2) { struct student *p1 = arg1; struct student *p2 = arg2; if (p1->num < p2->num) { return 1; } return 0; }
一个小demo
struct student { int num; //id char name[20]; //姓名 }; struct student stu[3] = { { 101, "liming" }, { 10, "zhangsan" }, { 103, "jenny" }, }; //函数调用 MySort(stu, sizeof(stu) / sizeof(struct student),sizeof(struct student),mycomparaperson);