回调函数实现qsort功能

回调函数(函数指针做函数参数)

本函数底层排序算法使用选择排序,实现对任意数组类型进行排序。

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);

 

上一篇:语言库中常用的排序算法底层结构qsort()


下一篇:快速排序