qsort函数详解

qsort(基本快速排序的方法,每次把数组分成两部分和中间的一个划分值,而对于有多个重复值的数组来说,基本快速排序的效率较低,且不稳定)。集成在C语言库函数里面的的qsort函数,使用 三 路划分的方法解决排序这个问题。所谓三路划分,是指把数组划分成小于划分值,等于划分值和大于划分值的三个部分。

具体介绍:
void qsort( void *base, size_t num, size_t width, int (__cdecl *compare ) (const void *elem1, const void *elem2 ) );

qsort(即,quicksort)主要根据你给的比较条件给一个快速排序,主要是通过指针移动实现排序功能。排序之后的结果仍然放在原来数组中。

参数意义如下:

第一个参数 base 是 需要排序的目标数组名(或者也可以理解成开始排序的地址,因为可以写&s[i]这样的表达式)

第二个参数 num 是 参与排序的目标数组元素个数

第三个参数 width 是单个元素的大小(或者目标数组中每一个元素长度),推荐使用sizeof(s[0])这样的表达式

第四个参数 compare 指向函数的指针,用于确定排序的顺序。就是让很多人觉得非常困惑的比较函数啦。
我们来简单讨论compare这个比较函数。典型的compare的定义是int compare(const void *a,const void *b);

返回值必须是int,两个参数的类型必须都是const void *,那个a,b是随便写的,个人喜好。假设是对int排序的话,如果是升序,那么就是如果a比b大返回一个正值(a 将被排在b后面),小则负值(a将被排在b前面),相等返回0(不变),其他的依次类推,后面有例子来说明对不同的类型如何进行排序。

#include<stdio.h>
#include<windows.h>

int cmp(const void* a, const void* b)
{
    return *(int*)a - *(int*)b;//升序
    //return *(int*)b - *(int*)a;降序
    //参数列表是两个通用类型指针,现在他要去指向你的数组元素。
    //所以转型为你当前的类型,然后取值。
    //升序排列时,若第一个参数指针指向的“值”大于第二个参数指针指向的“值”,则返回正(a将被排在b后面);
    //若第一个参数指针指向的“值”等于第二个参数指针指向的“值”,则返回零(a和b相等);
    //若第一个参数指针指向的“值”小于第二个参数指针指向的“值”,则返回负(a将被排在b后面)。
    //降序排列时,则刚好相反。
}

int cmp_d(const void* a, const void* b)
{
    return (*(double*)a > *(double*)b)?1:-1;
    //本来是因为要判断如果a==b返回0的
    //但是严格来说,两个double数是不可能相等的
    //只能说fabs(a-b)<1e-20之类的这样来判断,所以这里只返回了1和-1 
}

int cmp_f(const void* a, const void* b)
{
    return (*(float*)a > *(float*)b) ? 1:-1;
}

int cmp_c(const void* a, const void* b)
{
    return *(char*)a - *(char*)b;
}

int main()
{
    //对整型数组排序
    int arr[] = {5, 2, 3, 4, 1 };
    qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]), cmp);
    int i = 0;
    for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
    //对double型数组排序
    double arr1[] = { 1.15, 2.35, 1.46, 1.58, 1.66 };
    qsort(arr1, sizeof(arr1) / sizeof(arr1[0]), sizeof(arr1[0]), cmp_d);
    int j = 0;
    for (j = 0; j < sizeof(arr) / sizeof(arr[0]); j++)
    {
        printf("%lf ", arr1[j]);
    }
    printf("\n");
    //对float型数组排序
    float arr2[] = { 1.0, 5.0, 3.0, 4.0, 2.0 };
    qsort(arr2, sizeof(arr2) / sizeof(arr2[0]), sizeof(arr2[0]), cmp_f);
    int k = 0;
    for (k = 0; k < sizeof(arr) / sizeof(arr[0]); k++)
    {
        printf("%f ", arr2[k]);
    }
    printf("\n");
    //对字符型数组排序
    char arr3[] = { 'a', 'c', 'd', 'e', 'f',};
    qsort(arr3, sizeof(arr3) / sizeof(arr3[0]), sizeof(arr3[0]), cmp_c);
    int n = 0;
    for (n = 0; n < sizeof(arr) / sizeof(arr[0]); n++)
    {
        printf("%c ", arr3[n]);
    }
    printf("\n");
    system("pause");
    return 0;
}

程序运行结果:
这里写图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值