qsort函数C语言编译器函数库自带的排序函数,也叫快速排序函数。之前我写过一篇关于冒泡排序的代码讲解,大家感兴趣的话可以先看一看我对于冒泡排序的讲解。

相比较于冒泡排序,快速排序可以用更加快捷的速度去排列升降序,它的时间复杂度只有O(N*logN),冒泡排序的代码只能排列整型的数据,时间复杂度为O(n^2),比前者更高。(这么说吧,若是小明要从北京到上海,有两种方法,一种是坐火车(冒泡排序)去,一种是坐飞机(快速排序)去,由此可见其效率的不同。

        而快速排序函数qsort函数可以排列任何类型的数据,例如浮点型,字符型,结构体中可以按年龄大小排列,可以按名字首字母排列........

1.  qsort 的函数声明是:

void qsort(void*base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*)); 

        

2.参数共4个

  • base-- 指向要排序的数组的第一个元素的指针。

  • nitems-- 由 base 指向的数组中元素的个数。

  • size-- 数组中每个元素的大小,以字节为单位。

  • compare-- 用来比较两个元素的大小的一个函数,是函数指针(回调函数)

回调函数:

回调函数就是一个通过函数指针调用的函数。如果把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,就说这是回调函数。

对于第四个参数,函数指针指向的compare函数,其参数有两个,分别是两个元素的地址p1与p2:

设p1接收&arr[0],                 p2接收&arr[1]:

若*(void*)p1 > *(void*)p2,则返回大于0的值;

若*(void*)p1 = *(void*)p2,则返回等于0的值;

若*(void*)p1 < *(void*)p2,则返回小于0的值;

在函数指针中,void*表示空类型的指针(泛型指针),可以接收来自任何类型的元素地址,这就是快速排序函数可以排列多类型的核心要素。 

3.函数实践

接下来让我们欣赏一下快速排序的实验案例吧!

//qsort函数——快速排序# include<stdio.h>
#include<stdlib.h>int cmp_t(const void* p1, const void* p2) {return(*(int*)p1 - *(int*)p2);}
int main() {int arr[] = { 1,7,6,4,5,9,3,2,0,8 };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]),  cmp_t);int i = 0;for (i = 0; i < sz; i++) {printf("%d ", arr[i]);}return 0;
}

注:  在函数cmp_t中,p1-p2完成的是升列排序,p2-p1完成降列排序。 你可以根据想要的顺序进行两指针位置的调换。

 qsort传递的是指针,对于指针的比较,我们必须要将指针强制转化为相应的数据类型,比如排列浮点型数据,就将两指针强转为 (float*);排列字符型数据,就将两指针强转为( char*);排列结构体型数据就强转为( struct  结构体名称*)......


四.qsort函数对于其他类型的排序

1.qsort对于结构体数组的排序

#include<stdlib.h>
#include<string.h>
struct Stu {char name[15];int age;
};int cmp_t1(const void* p1, const void* p2) {//对姓名的排序return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}void test1() {struct Stu s[3] = { {"zhangsan",23},{"lisi",19},{"wangwu",30} };int sz = sizeof(s) / sizeof(s[0]);//qsort(s, sz, sizeof(struct Stu), cmp_t1);——对姓名的排序//打印数组
int i = 0;for (i = 0; i < sz; i++) {printf("%s ", s[i].name);printf("%d \n", s[i].age);}
}int main() {test1();return 0;
}

在上面的结构体成员变量中有姓名和年龄,我们可以选择姓名的首字母来进行对结构体数组的排序。姓名是字符串数据,那么我们便要使用字符串函数strcmp函数进行比较,还完美解决了回调函数返回值的问题

strcmp函数实现方法是对两组字符串中相应位置的比较,例如"abcdef"和" abcrgitho" 这两个字符串,从两字符串的首字符一对一对的比较,串1的a与串2的a比较,比较大小相同,再向后进行比较,直到在两字符串的第四位置,串1是d,串2是r,字符r的ASCII码值大于字符c,所以字符串2大,*e1- *e2,所以字符串2会排序到靠后的位置。

#include<stdlib.h>struct Stu {char name[15];int age;
};int cmp_t2(const void* p1, const void* p2) {//对年龄的排序return ((struct Stu*)p1)->age- ((struct Stu*)p2)->age;
}void test1() {struct Stu s[3] = { {"zhangsan",23},{"lisi",19},{"wangwu",30} };int sz = sizeof(s) / sizeof(s[0]);qsort(s, sz, sizeof(struct Stu), cmp_t2);//——对年龄的排序int i = 0;for (i = 0; i < sz; i++) {printf("%s ", s[i].name);printf("%d \n", s[i].age);}
}
int main() {test1();return 0;
}

2.qsort对浮点型数组的排序

//qsort对浮点型数据的排序int cmp_t(const void* p1, const void* p2) {return ((int)(*(float*)p1 - *(float*)p2));//float型指针相减的结果为float,需要强制转换为Int
}
int main() {float arr[] = { 9.0,8.0,7.0,6.0,5.0,4.0,3.0,2.0,1.0 };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_t);int i = 0;for (i = 0; i < sz; i++) {printf("%2f ", arr[i]);}return 0;

好了,对qsort函数的讲解就到这里,再次总结一下:qsort可以实现对任意类型数据的排序,功能强大,且需要掌握对四个参数的用法,尤其是第四个——函数指针,回调函数的使用。

C语言之——快速排序qsort库函数的讲解相关推荐

  1. C语言-排序-快速排序-qsort<stdlib.h>

    想到排序,大多数人第一个想到的都是冒泡排序,今天介绍一种函数,叫快速排序qsort函数,在讲这个函数之前,先将冒泡排序(数字)的代码给大家,如果想排序字符串,请大家使用strcmp函数即可 这是C语言 ...

  2. C语言快速排序--qsort函数

    C语言快速排序–qsort函数 一.什么是qsort函数 qsort函数是C语言编译器函数库自带的快速排序函数. 其包含在#include<stdlib.h>头文件里面,所以在使用的时候需 ...

  3. C语言程序设计之标准库快速排序qsort函数用法示例

    C语言程序设计之标准库快速排序qsort函数,排序效率高,使用方便,太棒了. qsort函数定义如下: #include <stdlib.h>void qsort(void *base, ...

  4. C语言排序算法 选择排序 插入排序 快速排序 qsort实现快排 堆排序

    常见排序算法 选择排序 选择排序(Selection sort)是一种简单直观的排序算法. 它的工作原理如下. 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素 ...

  5. C语言模拟实现标准库函数之qsort() 2

    C语言模拟实现标准库函数之qsort() <1> https://blog.csdn.net/csdn_kou/article/details/80158194 排序数字 int int_ ...

  6. C语言strcpy库函数的讲解

    C语言strcpy库函数的讲解 附1:MSDN关于strcpy库函数的简介 思路: 1.从上面的MSDN关于strcpy库函数的简介中,我们可以知道,传进函数的第一个参数是目标数组,也就是用来接收被拷 ...

  7. C语言strlen库函数的讲解

    C语言strlen库函数的讲解 附1:MSDN关于库函数strlen的解释 思路: 1.从MSDN中关于strlen库函数的讲解中我们可以知道的是,strlen库函数的头文件是<string.h ...

  8. qsort库函数详解

    目录 一.qsort是什么? 二.qsort的功能? 三.qosrt函数详解 1.qsort函数的定义 2.qsort函数的传参 四.qsort的模拟实现(冒泡) 1.如何实现交换? 2.如何实现字节 ...

  9. C语言——史上最全通讯录讲解(附源码)

    C语言--史上最全通讯录讲解(附源码) 一.开始界面的打印 二.对六大板块进行定义操作 三.对联系人进行初始化 四.对通讯录进行初始化 4.1动态版本 4.2静态版本 五.通讯录六大功能的具体实现 5 ...

最新文章

  1. 程序员的乐趣,生成自定义二维码,5 行 Python 代码就搞定
  2. 原 记录一下iOS开发中琐碎的点点_6
  3. Allegro 关闭与显示网络飞线
  4. Android接入百度自动更新SDK
  5. 开发板实现645协议C语言,迅为-imx6ull开发板之C语言实现LED例程
  6. 【CF487E】Tourists【圆方树】【树链剖分】【multiset】
  7. 【保存】java学习全套视频下载地址
  8. UML建模系列文章总结 [转]
  9. 使得最右边的元素右边框为0
  10. IDM出现输入用户名和密码不能下载解决方法
  11. PAT—1082 射击比赛(20)
  12. 拓端tecdat|Excel实例:排序和筛选2
  13. js面向对象练习(二):JS面向对象的思路(canvas)写躁动的小球
  14. oracle12c linux安装教程
  15. 24X24 黑体简体中文点阵字库
  16. linux的tar命令详情;linux多个文件压缩打包到一个压缩文件
  17. 电脑进程说明,常见,作用,说明,是否,查看,问题
  18. softmax溢出问题
  19. UEBA架构设计之路1
  20. Windows API一日一练(20)LoadIcon和LoadCursor函数-程序图标设置和鼠标的样式

热门文章

  1. ipad分屏_iPadOS 上手:桌面级体验,让 iPad 离生产力更近一步
  2. 后街男孩AND西城男孩
  3. hp计算机指纹功能用法,都9102年了 你居然问我指纹解锁开机是个啥?
  4. FL STUDIO水果21版本新主题、插件、功能介绍
  5. nginx部署https域名
  6. 命令行下开启与关闭windows防火墙关端口(转)
  7. npm 编译报错extract:echarts:sillextract echarts@^4.2.0-rc.2 extracted to
  8. 《算法设计与分析(第4版)》课后习题第二章第2小题
  9. PHP常见日期和时间函数及其用法
  10. 【Django入门】——查询集QuerySet介绍