天天看點

【C語言】使用回調函數通過冒泡排序模拟實作qsort函數

回調函數是什麼?

回調函數:

就是一個通過函數指針調用的函數。如果你把函數的指針(位址) 作為參數傳遞給另一個函數,當這個指針被用來調用其所指向的函數時,我們就說這是回調函數。回調函數不是由該函數的實作方直接調用,而是在特定的事件或條件發生時由另外的一方調用的,用于對該事件或條件進行響應。

先來舉個qsort函數的使用案例:

qsort()函數:

聲明:

【C語言】使用回調函數通過冒泡排序模拟實作qsort函數
參數:
【C語言】使用回調函數通過冒泡排序模拟實作qsort函數
這裡用到qsort函數實作對數組元素的從小到大排序
【C語言】使用回調函數通過冒泡排序模拟實作qsort函數
運作結果如下:
【C語言】使用回調函數通過冒泡排序模拟實作qsort函數

qsort函數排序運用的是快速排序算法

接下來就要來實作一個與之類似的冒泡排序函數

具體過程注意看下列 完整代碼注釋

#include <stdio.h>
#include<string.h>
struct Stu
{
    char name[20];
    int age;
};
//比較結構體年齡
int cmp_by_age(const void* e1, const void* e2)
{
    return ((struct Stu*)e1)->age -((struct Stu*)e2)->age;
}
//比較結構體姓名
int cmp_by_name(const void*e1, const void*e2)
{
    return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
//比較整型數
int cmp_int(const void* e1, const void*e2)
{
    return *(int*)e1 - *(int*)e2;
}
//列印函數
void print_arr(int arr[], int sz)
{
    int i = 0;
    for (i = 0; i < sz; i++)
    {
        printf("%d ", arr[i]);
    }
}

//交換函數
void Swap(char* buf1, char* buf2, int width)
{
    int i = 0;
    for (i = 0; i < width; i++)
    {
        char tmp = *buf1;
        *buf1 = *buf2;
        *buf2 = tmp;
        buf1++;
        buf2++;
    }
}
//使用回調函數實作一個通用冒泡排序
void BubbleSort(void* base, size_t num, size_t width, int (*cmp)(const void*, const void*))
{
    size_t i = 0;
    //趟數
    for (i = 0; i < num - 1; i++)
    {
        //比較的對數
        size_t j = 0;
        for (j = 0; j < num - 1 - i; j++)
        {
            //base[j] ==> *(base+j)
            if (cmp((char*)base+j*width, (char*)base+(j+1)*width)>0)
            {
                //交換
                Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
            }
        }
    }
}

//整型數組排序測試
void test1()
{
    int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
    int sz = sizeof(arr) / sizeof(arr[0]);
    BubbleSort(arr, sz, sizeof(arr[0]), cmp_int);
    //列印
    print_arr(arr, sz);
}

//結構體排序測試
void test2()
{
    struct Stu s[3] = { {"zhangsan", 15}, {"lisi", 30},{"wangwu", 10} };
    int sz = sizeof(s) / sizeof(s[0]);
    //按照名字排序
    BubbleSort(s, sz, sizeof(s[0]), cmp_by_name);
    
    //按照年齡來排序
    BubbleSort(s, sz, sizeof(s[0]), cmp_by_age);

}
int main()
{
    

    //測試自定義的BubbleSort()排序整型數組
    test1();
    //測試自定義的BubbleSort()排序結構體
    test2();
    return 0;
}
      

這個冒泡排序函數是一個通用函數,不光可以對整型數組進行排序,也可以對結構體資料進行排序,需要變化的就隻是比較函數而已

【C語言】使用回調函數通過冒泡排序模拟實作qsort函數

整型數組排序:

【C語言】使用回調函數通過冒泡排序模拟實作qsort函數

結構體資料按名字排序:

【C語言】使用回調函數通過冒泡排序模拟實作qsort函數

結構體資料按年齡排序:

【C語言】使用回調函數通過冒泡排序模拟實作qsort函數

繼續閱讀