c语言qsort函数(快速排序)

c语言qsort函数(快速排序)

在学习c语言时我们常常会遇到一些排序的问题,在遇到这些排序的问题的时候,我们当然可以自己选择写出自己的排序方法来进行排序。但是我们今天要介绍的是c语言库函数中所提供的一个快排函数。这个函数可以直接提供给我们快排这样一个工具,在面对一些情况的时候会起到事半功倍的效果。此外,它能够排序任意数据类型的数组其中包括整形,浮点型,字符串甚至还有自定义的结构体类型,合理使用时非常方便。

一.qsort函数的参数

下图为cplusplus.com的标准库函数说明

其函数声明如下

void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));

1.首元素地址base

我们要排序一组数据,首先我们需要找到这组数据在哪,因此我们直接将首元素的地址传给qsort函数的指针void*来确定从这个数组的哪个地方开始排序。

2.元素的个数num

我们将需要排序的元素的个数传给qsort函数来确定一组数据。这是因为我们知道了从哪开始,也要知道在哪结束才能确定一组需要排序的数据,但是我们不方便直接将结尾元素的地址传入函数。

3.元素大小size

我们需要将元素大小传入qsort函数。qsort函数能排序任意数据类型的一组数据,因此我们用void*类型的指针来接收元素,但是我们知道void*类型的指针不能进行加减操作,也就是说无法移动。那么在函数内部我们究竟用什么类型的指针来操作变量呢?其实在函数内部,我们可以将void*类型的指针强制类型转换成char*类型的指针后来逐个字节地来操作元素,因为char*类型的指针移动的单位字节长度是1个字节,我们只需要知道需要操作的数据是几个字节就可以实现指针从一个元素恰好能够移动到下一个元素。

4.用户自定义的比较函数compar

我们需要告诉qsort函数我们希望数据按照怎么的方式进行比较。同需要传递元素个数的道理一样,qsort函数能排序任意数据类型的一组数据,因此库函数用void*类型的指针来指定我们我们编写的比较方式,可以起到不把函数写死,根据实际情况的需要写的作用。同时我们可以看到编写的函数的返回值大于零时,qsort函数会将数组里面前一个元素放在后一个元素后面,也就是两个元素进行调换。

二.比较函数的书写

qsort函数给cmpar函数规定了特定的参数const void* 。因此我们自定义函数时要严格遵守其参数设定。

如果你需要比较的是整形数组,你需要将比较函数中void*强制转换成int *,同时如果你希望qsort

进行升序快排,我们需要使得前一个数字比后一个数字大的时候返回1.

int compar(const void* e1, const void* e2)
{
    return *(int*)e1 - *(int*)e2;
}

同理如果需要进行降序快排的话

int compar(const void* e1, const void* e2)
{
    return *(int*)e2 - *(int*)e1;
}

比较的是字符串的大小,并进行升序快排的话:

int compare_str(const void* e1, const void* e2)
{
    return strcmp((char*)e1, (char*)e2);
}

比较的是字符串的长度,并进行升序快排的话:

int cmp_str_len(const void* e1, const void* e2)
{
    return strlen((char*)e1)-strlen((char*)e2);
}

比较结构体时需要指明需要比较的具体变量,就像我们不能比较一个人,除非有相应的标准:

int cmp_struct_stu_name(const void* e1, const void* e2)
{
    return strcmp(   ((struct stu*)e1)->name, ((struct stu*)e2)->name );
}
int cmp_struct_stu_GPA(const void* e1, const void* e2)
{
    return (  ((struct stu*)e2)->GPA - ((struct stu*)e1)->GPA  );
}

三.实例演示

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
struct stu
{
    char name[20];
    float GPA;
};
int compare_str(const void* e1, const void* e2)
{
    return strcmp((char*)e1, (char*)e2);
}
int cmp_str_len(const void* e1, const void* e2)
{
    return strlen((char*)e1) - strlen((char*)e2);
}
int cmp_struct_stu_name(const void* e1, const void* e2)
{
    return strcmp(   ((struct stu*)e1)->name, ((struct stu*)e2)->name   );
}
int cmp_struct_stu_GPA(const void* e1, const void* e2)
{
    return (  ((struct stu*)e2)->GPA - ((struct stu*)e1)->GPA  );
}
int main()
{
    int i = 0;
    struct stu s[3] = { {"zhangsan",3.4} ,{"zhangmazi",4.0} ,{"dingzhen",1.0} };
    qsort(s, 3, sizeof(s[0]), cmp_struct_stu_name);
    for (i = 0; i < 3; i++)
    {
        printf("%s  %f\n", s[i].name, s[i].GPA);
    }
        qsort(s, 3, sizeof(s[0]), cmp_struct_stu_GPA);
    for (i = 0; i < 3; i++)
    {
        printf("%s  %f\n", s[i].name, s[i].GPA);
    }

}

可以看到只需要我们按要求写好参数qsort函数就能够帮我们对元素进行排序。

四.函数所需要的头文件

包含在stdlib.h头文件中,函数一共有四个参数,没有返回值。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

脆皮骷髏人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值