C语言qsort函数使用详解

qsort函数的功能与使用

qsort是C标准库中提供的快速排序函数,强大的点在于其可以对任意类型的数组进行排序。核心优势在于通过回调函数实现泛型排序,适用于各种数据类型。

函数定义如下:

    void qsort( void *base,  //指向待排序的数组
               size_t num,  //待排序的个数 
              size_t width, //待排序的元素大小
              int (__cdecl *compare )(const void *elem1, const void *elem2 ) );
                //提供的比较方式
    • base         指向待排序的数组首元素地址
    • sum          数组中元素个数
    • width        单个元素的字节大小
    • compare   比较函数的指针(需要自己定义) 
      • 若需要将数组按照升序排列,当elem1>elem2时候返回大于0的值,反之则反

    使用实例:
    假设现在有一个无序的整数数组,需要对其按照升序排序

    #include <stdlib.h>
    #include <stdio.h>
    
    int compare_int(const void* a, const void* b) {
        return (*(int*)a - *(int*)b);
    }//自定义的compare 适用于int类型
    
    int main() {
        int arr[] = {5, 2, 9, 1, 5};
        qsort(arr, 5, sizeof(int), compare_int);
        for (int i = 0; i < 5; i++) printf("%d ", arr[i]);
        // 输出:1 2 5 5 9
    }
     
    

    针对不同数据类型

    以下示例展示了如何定制比较函数,覆盖常见数据类型。每个示例都使用qsort进行排序,并输出结果。

    示例1: 整数类型(int)
    使用减法直接比较,但需注意整数溢出风险(对于大数)。建议优先使用比较运算符(如<>)以避免问题。

    #include <stdlib.h>
    #include <stdio.h>
    
    int compare_int(const void* a, const void* b) {
        int int_a = *(const int*)a;
        int int_b = *(const int*)b;
        if (int_a < int_b) return -1;
        if (int_a > int_b) return 1;
        return 0;
        // 或者简化版(但有溢出风险): return (*(int*)a - *(int*)b);
    }
    
    int main() {
        int arr[] = {5, 2, 9, 1, 5};
        size_t num = sizeof(arr) / sizeof(arr[0]);
        qsort(arr, num, sizeof(int), compare_int);
        for (size_t i = 0; i < num; i++) printf("%d ", arr[i]); // 输出: 1 2 5 5 9
    }
    

    示例2: 浮点数类型(double)
    浮点数比较涉及精度问题,不能直接使用减法(因为减法可能受浮点误差影响)。

    #include <stdlib.h>
    #include <stdio.h>
    
    int compare_double(const void* a, const void* b) 
    {
    	double double_a = *(const double*)a;
    	double double_b = *(const double*)b;
    	if (double_a < double_b) 
    		return -1;
    	if (double_a > double_b) 
    		return 1;
    	return 0;
    }
    
    int main() 
    {
    	double arr[] = { 3.14, 1.59, 2.65, 0.01 };
    	size_t num = sizeof(arr) / sizeof(arr[0]);
    	qsort(arr, num, sizeof(double), compare_double);
    	for (size_t i = 0; i < num; i++) 
    		printf("%.2f ", arr[i]); // 输出: 0.01 1.59 2.65 3.14
    }
    

    示例3: 字符串类型(char)*
    字符串比较不能使用减法,需调用strcmp函数(来自<string.h>strcmp直接返回所需的负数、零或正数。

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    int compare_string(const void* a, const void* b) 
    {
    	const char* str_a = *(const char**)a; // 注意:数组元素是char*,所以需解引用为指针的指针
    	const char* str_b = *(const char**)b;
    	return strcmp(str_a, str_b);
    }
    
    int main() 
    {
    	const char* arr[] = { "apple", "banana", "cherry", "date" };
    	size_t num = sizeof(arr) / sizeof(arr[0]);
    	qsort(arr, num, sizeof(char*), compare_string);
    	for (size_t i = 0; i < num; i++) 
    		printf("%s ", arr[i]); // 输出: apple banana cherry date
    }

    示例4: 结构体类型(struct)
    结构体排序通常基于某个字段(如id或name)。比较函数需提取字段值进行比较。

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    typedef struct {
    	int id;
    	char name[20];
    } Person;
    
    int compare_person_by_id(const void* a, const void* b) 
    {
    	const Person* person_a = (const Person*)a;
    	const Person* person_b = (const Person*)b;
    	if (person_a->id < person_b->id) 
            return -1;
    	if (person_a->id > person_b->id) 
            return 1;
    	return 0;
    }
    
    int compare_person_by_name(const void* a, const void* b) 
    {
    	const Person* person_a = (const Person*)a;
    	const Person* person_b = (const Person*)b;
    	return strcmp(person_a->name, person_b->name);
    }
    
    int main() {
    	Person arr[] = { {3, "Alice"}, {1, "Bob"}, {2, "Charlie"} };
    	size_t num = sizeof(arr) / sizeof(arr[0]);
    
    	// 按id排序
    	qsort(arr, num, sizeof(Person), compare_person_by_id);
    	printf("按id排序: ");
    	for (size_t i = 0; i < num; i++) 
    		printf("%d:%s ", arr[i].id, arr[i].name); // 输出: 1:Bob 2:Charlie 3:Alice
    
    	// 按name排序
    	qsort(arr, num, sizeof(Person), compare_person_by_name);
    	printf("\n按name排序: ");
    	for (size_t i = 0; i < num; i++) 
    		printf("%d:%s ", arr[i].id, arr[i].name); // 输出: 3:Alice 1:Bob 2:Charlie
    }
    

    需要注意的是,compare函数中的返回值,对于数值类型,减法虽然简便,但是需警惕溢出问题或者精度问题。其次,在强制转换指针时,确保类型匹配。 

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值