用回调函数实现冒泡排序

(一)什么是回调函

       答:回调函数就是通过函数指针调用的函数如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。

(二)回调函数的实现机制

        1.定义一个回调函数

        2.提供函数实现的一方在初始化时。将回调函数的函数指针注册给调用者。

        3.当特定的条件发生时,调用者使用函数指针调用回调函数对事件进行处理。

(三)回调函数的使用原因

       通过回调函数,可以将调用者与被调用者分开。


       可能你不知道,在库函数中有一个qsort函数,即我们通常说的快速排序,让我们看它是如何调用和实现的。

原型:void qsort( void *base, size_t num, size_t width

           int (__cdecl *compare ) (const void *elem1, const void *elem2 ) )

base:目标数组的首位置

num:元素个数

width:每个元素所占字节数

compare:函数指针,指向一个比较函数

#define _CRT_SECURE_NO_WARNINGS 1  
#include<stdio.h>  
#include<stdlib.h>  
#include<string.h>  
  
  
int compare_int(const void *elem1,const void *elem2)//排序整型数组  
{  
    return *(int *)elem1-*(int *)elem2;  
}  
  
int compare_float(const void *elem1,const void *elem2)//排序浮点型数组  
{  
    if((*(float *)elem1)-(*(float *)elem2) > 0)//不可以直接返回二者的差,\  
                                             转化为整型时可能漏掉部分数据       
         return 1;  
  
    else if((*(float *)elem1)-(*(float *)elem2) == 0)  
         return 0;  
  
    else  
         return -1;  
}  
  
int compare_string(const void *elem1,const void *elem2)、  
{  
    return strcmp(*(char **)elem1,*(char **)elem2);//应先找到每个字符串\  
                                                     的首地址再进行解引用  
}  
  
void print_int_arr(int arr[],int sz)  
{  
    int i = 0;  
    for(i=0; i<sz; i++)  
    {  
        printf("%d ",arr[i]);  
    }  
    printf("\n");  
}  
void print_float_arr(float arr[],int sz)  
{  
    int i = 0;  
    for(i=0; i<sz; i++)  
    {  
        printf("%f ",arr[i]);  
    }  
    printf("\n");  
}  
void print_string_arr(char **arr,int sz)  
{  
    int i = 0;  
    for(i=0; i<sz; i++)  
    {  
        printf("%s ",arr[i]);  
    }  
    printf("\n");  
}  
int main()  
{  
    int arr1[]={2,4,6,8,0,1,3,5,7,9};  
    int sz1 = sizeof(arr1)/sizeof(arr1[0]);  
    float arr2[]={2.0f,4.4f,6.5f,8.3f,0.0f,1.2f,3.7f,5.6f,7.9f,9.8f};  
    int sz2 = sizeof(arr2)/sizeof(arr2[0]);  
    char *arr3[]={"abcd", "bbdd", "aabc", "dfer","dghjf"};  
    int sz3 = sizeof(arr3)/sizeof(arr3[0]);  
    qsort(arr1,sz1,sizeof(int),compare_int);  
    qsort(arr2,sz2,sizeof(int),compare_float);  
    qsort(arr3,sz3,sizeof(int),&compare_string);  
    print_int_arr(arr1,sz1);  
    print_float_arr(arr2,sz2);  
    print_string_arr(arr3,sz3);  
    system("pause");  
    return 0;  
}  

程序运行结果:


是的,你没看错,通过回调函数,我们同时排序了不同类型的数组元素,是不是很方便呢,同时让程序也更灵活了。



通过上面的调用和部分实现,让我们来一起模拟一个通过回调函数实现冒泡排序的算法吧!

#define _CRT_SECURE_NO_WARNINGS 1  
#include<stdio.h>  
#include<stdlib.h>  
#include<string.h>  
  
int compare_int(const void *elem1,const void *elem2)  
{  
    return *(int *)elem1-*(int *)elem2;  
}  
  
int compare_float(const void *elem1,const void *elem2)  
{  
    if((*(float *)elem1)-(*(float *)elem2) > 0)//不可以直接返回二者的差,\  
                                               //转化为整型时可能漏掉部分数据       
         return 1;     
  
    else if((*(float *)elem1)-(*(float *)elem2) == 0)  
         return 0;  
  
    else  
         return -1;  
}  
  
int compare_double(const void *elem1,const void *elem2)  
{  
    if((*(double *)elem1)-(*(double *)elem2) > 0)//不可以直接返回二者的差,\  
                                             //转化为整型时可能漏掉部分数据       
         return 1;  
  
    else if((*(double *)elem1)-(*(double *)elem2) == 0)  
         return 0;  
  
    else  
         return -1;  
}  
  
int compare_char(const void *elem1,const void *elem2)  
{  
    return *(char *)elem1-*(char *)elem2;//应先找到每个字符串\  
                                         // 的首地址再进行解引用  
}  
  
int compare_string(const void *elem1,const void *elem2)  
{  
    return strcmp(*(char **)elem1,*(char **)elem2);//应先找到每个字符串\  
                                                   // 的首地址再进行解引用  
}  
  
void Swap(size_t width,void *n1,void *n2)  
{  
    char tmp = 0;  
    size_t i = 0;  
    for(i=0; i<width; i++)  
    {  
        tmp=*((char *)n1+i);  
        *((char *)n1+i)=*((char *)n2+i);  
        *((char *)n2+i)=tmp;  
    }  
}  
void bubble_sort(void *base,size_t sz,size_t width,  
                int (*compare)(const void*,const void*))  
{  
    size_t i = 0;  
    size_t j = 0;  
    for(i=0; i<sz-1; i++)  
    {  
        for(j=0; j<sz-1-i; j++)  
        {  
            <span style="color:#ff0000;">if(compare(((char*)base+j*width),((char *)base+(j+1)*width))>0)//升序  
            //if(compare((char *)base+j*width),(char *)base+(j+1)*width)>0)//降序  
            Swap(width,((char *)base+j*width),((char *)base+(j+1)*width));</span>  
        }  
    }  
}  
void print_int_arr(int arr[],int sz)  
{  
    int i = 0;  
    for(i=0; i<sz; i++)  
    {  
        printf("%d ",arr[i]);  
    }  
    printf("\n");  
}  
void print_float_arr(float arr[],int sz)  
{  
    int i = 0;  
    for(i=0; i<sz; i++)  
    {  
        printf("%f ",arr[i]);  
    }  
    printf("\n");  
}  
void print_double_arr(double arr[],int sz)  
{  
    int i = 0;  
    for(i=0; i<sz; i++)  
    {  
        printf("%lf ",arr[i]);  
    }  
    printf("\n");  
}  
void print_char_arr(char arr[],int sz)  
{  
    int i = 0;  
    for(i=0; i<sz; i++)  
    {  
        printf("%c ",arr[i]);  
    }  
    printf("\n");  
}  
void print_string_arr(char *arr[],int sz)  
{  
    int i = 0;  
    for(i=0; i<sz; i++)  
    {  
        printf("%s ",arr[i]);  
    }  
    printf("\n");  
}  
int main()  
{  
    int arr1[]={2,4,6,8,0,1,3,5,7,9};  
    int sz1 = sizeof(arr1)/sizeof(arr1[0]);  
    float arr2[]={2.0f,4.4f,6.5f,8.3f,0.0f,1.2f,3.7f,5.6f,7.9f,9.8f};  
    int sz2 = sizeof(arr2)/sizeof(arr2[0]);  
    double arr3[]={1.1,2.4,3.5,4.6,7.8,9.0};  
    int sz3 = sizeof(arr3)/sizeof(arr3[0]);  
    char arr4[]={'d','f','b','c','e','g','h','a'};  
    int sz4 = sizeof(arr4)/sizeof(arr4[0]);  
    char *arr5[]={"abcd", "bbdd", "aabc", "dfer","dghjf"};  
    int sz5 = sizeof(arr5)/sizeof(arr5[0]);  
    bubble_sort(arr1,sz1,sizeof(int),compare_int);  
    bubble_sort(arr2,sz2,sizeof(float),compare_float);  
    bubble_sort(arr3,sz3,sizeof(double),compare_double);  
    bubble_sort(arr4,sz4,sizeof(char),compare_char);  
    bubble_sort(arr5,sz5,sizeof(char *),compare_string);  
    print_int_arr(arr1,sz1);  
    print_float_arr(arr2,sz2);  
    print_double_arr(arr3,sz3);  
    print_char_arr(arr4,sz4);  
    print_string_arr(arr5,sz5);  
    system("pause");  
    return 0;  
}  

各种类型的数据都可调用一个函数来排序了,怎么样,你学会了吗?



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值