boxmoe_header_banner_img

欢迎来到KAZAMATA'S WEBSITE

加载中

C标准库快速排序qsort


avatar
kazamata 2026年11月4日 2026年11月4日 112

使用qsort快速排序需要用到头文件stdlib.h,头文件里面包含了qsort函数的声明:

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

函数不返回任何东西。*base要求输入待排序的数组的首地址;size_t nitems要求输入元素个数;size_t size要求输入每个元素所占的字节数;compar是自定义比较函数。

返回值规则: 以compar(a,b)为例

  1. 如果compar返回负数,则a排在b前面
  2. 如果compar返回正数,则b排在a前面

qsort 底层是快速排序:选一个基准值 pivot,一趟把数组分成两部分:小于 pivot 放一边、大于 pivot 放另一边;再递归左右两个子区间。 平均时间复杂度:O(n\log n) 最坏情况:O(n^2)(标准库一般做了优化,比如三数取中,竞赛基本够用)

注意:qsort 不稳定排序(相等元素的相对顺序可能打乱,比如说2_2与2_1,按理来说2_1在从小到大排序的时候应该排在2_2之前,而qsort认为这两个元素并无不同,所以他们的位置既可能是2_2在前,也可能是2_1在前,并不确定,在涉及相同元素不同属性的排序的时候不能用qsort)

int降序代码

int cmp(const void *a, const void *b) {    
    int x = *(int *)a;    
    int y = *(int *)b;    
    if(x > y) return -1;    
    if(x < y) return 1;    
    return 0; 
} 

调用方式:qsort(list, n, sizeof(int), cmp);

int降序代码原理:qsort接收数组地址、元素数量、单个元素字节大小、比较函数的地址,然后以pivot基准值做划分并递归处理。划分过程中需要不断比较两个元素的大小,大小关系由传入的比较函数决定。 qsort会把数组里的两个元素a、b封装成const void*类型的地址传给compar比较函数。compar拿到这两个无类型指针后,先强制转换成int指针,再解引用取出a、b的原值,接着对比原值:如果a大于b就返回-1,如果a小于b就返回1。qsort根据返回值判断顺序:返回-1时,a排在b前面;返回1时,b排在a前面,最终实现大数在前、小数在后的降序排序。

当然如果说需要升序代码,则把return的值相互调换即可,如果需要比较float、double、long long等类型的数组,则只需要改变qsort的size_t size值即可。

qsort也可以比较结构体类型的数据,示例:

int cmp_stu(const void *a, const void *b) {    
    // 把 void* 转成结构体指针    
    struct Student *sa = (struct Student *)a;    
    struct Student *sb = (struct Student *)b;     
    
    // 拿结构体里面的成员对比    
    if(sa->score > sb->score) return -1;    
    if(sa->score < sb->score) return 1;    
    return 0; 
}

如果你有更好的算法,不妨点击此处提交
提交到 KAZAMATA DEV C++

无需登录:打开后填写昵称即可提交,并计入贡献排行榜

贡献排行榜

排行榜加载中…
上一次更新已经跑远了 计算中...
(‾◡◝) 本内容里的一些消息,可能已经跟不上时间啦~


评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字
插入代码
后退
前进
刷新
复制
粘贴
全选
删除
返回首页
0%
目录
顶部
底部
文章导读