【排序】什么都能排的C语言qsort排序详解【超详细的宝藏级别教程】深度理解qsort排序

作者: @小小Programmer
这是我的主页:@小小Programmer
在食用这篇博客之前,博主在这里介绍一下其它高质量的编程学习栏目:
数据结构专栏:数据结构 这里包含了博主很多的数据结构学习上的总结,每一篇都是超级用心编写的,有兴趣的伙伴们都支持一下吧!
算法专栏:算法 这里可以说是博主的刷题历程,里面总结了一些经典的力扣上的题目,和算法实现的总结,对考试和竞赛都是很有帮助的!

先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说是一种非常重要的动力。看完之后别忘记关注我哦!️️️

本篇建议收藏后食用~

博主之前,也发表过一篇有关排序的博客,里面包含了九大排序的详细剖析,也是干货满满的宝藏噢,需要的伙伴可以通过传送门食用~【排序】万字九大排序宝藏汇总 轻松拿下九大排序算法【带动画】 (包含超详细的解释和注释)

文章目录

  • qsort函数的使用方法
  • qsort的模拟实现(冒泡思想)
  • 尾声

qsort函数的使用方法

qsort的简介:
图片来自www.cplusplus.com

使用举例:

//1.排序整型
#if 1
int cmp_int(const void* e1, const void* e2) {return +(* (int*)e1 - *(int*)e2);
}
void _OutputArr(int* arr, int sz) {for (int i = 0; i < sz; i++) {printf("%d ", arr[i]);}
}
int main() {int arr[] = { 9,8,7,6,5,4,3,2,1,10 };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_int);_OutputArr(arr, sz);return 0;
}
#endif

接下来,让我们对着函数简介那张图,和这个使用举例,来剖析qsort函数的使用方法:

函数原型:

参数分析:

  • 第一个参数:void*base,指待排序的序列(可以是任何类型的数据)的地址
  • 第二个参数:size_t num,指元素个数。
  • 第三个参数:size_t width,指每个元素的大小(单位是字节),因为qsort排序的作者,是不知道我们将要用qsort来排什么类型的数据的,如果是int类型,就是四个字节一个元素,如果是char类型,就是一个字节,如果是结构体类型,可能会更大,所以,我们在使用qsort来对数据进行排序的时候,我们必须告诉qsort,一个元素占几个字节。
  • 第四个参数:int(*cmp)(const void*e1,const void*e2) 这是一个函数指针,而cmp这个函数是由使用者自己编写的,用来告诉qsort,什么叫做大,什么叫做小。

    由这张图我们可以清晰的知道,如果cmp返回一个小于零的数字,说明e1比e2小
    等于0大于0同理。

以上便是qsort函数使用的剖析,接下来,我们举多一个例子,加深一下印象:我们来排序一些结构体数据

struct Stu {char name[20];int age;double score;
};
int cmp_stu_by_age(const void* e1, const void* e2) {return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
int cmp_stu_by_name(const void* e1, const void* e2) {return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
int main() {struct Stu arr[3] = { {"zhangsan",20,55.5},{"lisi",30,88},{"wangwu",10,90.0} };int sz = sizeof(arr) / sizeof(arr[0]);//qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_age);qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_name);//这里就不打印了,我们可以调试看到排序的结果 return 0;
}

看到这里,相信我们已经被qsort这个万能的排序工具深深吸引了。其实,qsort远没有我们想象的那么复杂,接下来,让我们一起模拟实现它!

qsort的模拟实现(冒泡思想)

qsort()在库里面是基于快速排序的思想实现的,但是今天我们学习的重点是实现qsort里面的其它细节,而不是排序思想。因此,今天我们使用比较简单的冒泡排序思想来实现这个qsort

我们来看实现源码:

void swap(char* bulf1, char* bulf2, int width) {//因为我们不知道要交换多少//一次交换一个字节int i = 0;for (i = 0; i < width; i++) {char tmp = *bulf1;*bulf1 = *bulf2;*bulf2 = tmp;bulf1++;bulf2++;}
}
void my_qsort_ByBubble(void* base, size_t num, size_t width, int(*cmp)(const void* e1, const void* e2)) {int i = 0;int j = 0;for (i = 0; i < num - 1; i++) {for (j = 0; j < num - 1 - i; j++) {//交换if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0) {//交换swap((char*)base + j * width, (char*)base + (j + 1) * width, width);//由于我们不知道到底要交换多少字节//所以传width}}}
}

注意:
由于void*类型是不能进行解引用的,而作为qsort的作者,我们也不知道将来要用来排序的数据是什么类型的,因此,最方便的方式就是将void*类型强转位char*类型,再乘上width,我们就可以得到我们需要的指针类型了。

尾声

看到这里,相信你对qsort这个库函数已经有了一定认识,如果你感觉这期博客对你有帮助的话,请不要吝啬你们的点赞收藏和关注哦

【排序】什么都能排的C语言qsort排序详解【超详细的宝藏级别教程】深度理解qsort排序相关推荐

  1. C语言二叉查找树(图文详解)(超详细)

    二叉查找树 本人在第一次学习二叉树的时候,感觉很懵懵懂懂,勉强知道了二叉树的结构和查找方式,但要我自己去动手写的时候,可是难上加难,所以这里我用干货+实际例子的方式让你上手二叉树,这个例子几乎可以套用 ...

  2. 八大排序详解-超详细

    目录 概述 一,选择排序-直接插入排序(Direct insertion sort) 二,插入排序-希尔排序(Shell sort) 三,选择排序-简单选择排序(Simple selection so ...

  3. python自动解析json_Python语言解析JSON详解

    本文主要向大家介绍了Python语言解析JSON详解,通过具体的内容向大家展示,希望对大家学习Python语言有所帮助. JSON 函数使用 JSON 函数需要导入 json 库:import jso ...

  4. (转)C语言位运算详解

    地址:http://www.cnblogs.com/911/archive/2008/05/20/1203477.html C语言位运算详解 作者:911 说明:本文参考了http://www2.ts ...

  5. python语言的格式框架_django框架模板语言使用方法详解

    本文实例讲述了django框架模板语言使用方法.分享给大家供大家参考,具体如下: 模板功能 作用:生成html界面内容,模版致力于界面如何显示,而不是程序逻辑.模板不仅仅是一个html文件,还包括了页 ...

  6. C语言再学习 -- 详解C++/C 面试题 2

    (经典)C语言测试:想成为嵌入式程序员应知道的0x10个基本问题. 参看:嵌入式程序员面试问题集锦 1.用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define ...

  7. 计算机科学类专升本复习之“C语言结构体”详解(初稿)

    C语言结构体详解,C语言struct用法详解 前面所学到的"数组":它是一组具有"相同类型"的数据的集合. 但是在实际的编程中,我们往往还需要 一组" ...

  8. C语言结构体详解(结构体定义,使用,结构体大小等)

    c语言结构体详解 1.c语言结构体 1.1 结构体基础知识 1.2 结构体声明 1.3 结构体特殊声明 1.4 结构体的自引用 1.5 结构体的大小的计算 1.5.1了解结构体大小计算规则 1.5.2 ...

  9. C语言中编译预处理命令作用,C语言预处理命令详解

    原标题:C语言预处理命令详解 关注百问科技并将它设为星标 不错过任何一篇嵌入式干货 ------ 作者:clover_toeic 原文出处: https://www.cnblogs.com/clove ...

最新文章

  1. win服务器发展方向是什么?
  2. 浏览器中遮罩层镂空效果的多种实现方法
  3. 【LeetCode从零单排】No28 Implement strStr()
  4. IP选路与动态选路协议(六)
  5. python拼图游戏代码的理解_Python加pyGame实现的简单拼图游戏实例
  6. ArcGIS API For JS之网络分析(临近设施分析)
  7. 如何实现rtsp h265 转 rtmp (rtsp hevc 转 rtmp)并转发到CDN或自建服务器
  8. 织梦响应式鲜花绿植花艺类网站模板(自适应手机端)
  9. 移动端页面按手机屏幕分辨率自动缩放的js
  10. 两个空间点直接距离投影公式_HBAO(屏幕空间的环境光遮蔽)
  11. php中显示不出来,图片显示不出来,但是数据库里有显示
  12. python爬虫bs4_Python爬虫系列-Xpath自如和bs4链家
  13. java gbk文件转utf8_java 将GBK编码文件转为UTF-8编码
  14. Pandas学习笔记- DataFrame
  15. 软件工程计算机组成原理,软件工程--0计算机组成原理.pdf
  16. UBUNTU18.04系统安装打印机
  17. C4D插件X-Particles粒子特效(二)
  18. Ubuntu安装字体for wps
  19. 快捷键Ctrl+s快速保存,屏蔽保存网页到本地
  20. Visio 2013画直线问题总结(折线变直,交叉时产生的交叉桥)

热门文章

  1. 微信SDK开发学习第二课
  2. 入侵Linux服务器,黑客惯用手法:提权
  3. hydrogenos是鸿蒙系统吗,系统体验:氢氧结合会变成水吗?
  4. 自学Java day53 使用jvav实现 BitMap 数据结构 从jvav到架构师
  5. Webix - JavaScript UI 9.2.0
  6. 实战案例:带你了解并验证基金定投,附Python代码!
  7. xray与burp/rad联动
  8. 在ArcGIS中利用降雨量数据进行克里金插值
  9. java登录时启动后台异步线程_JAVA多线程的同步和 异步
  10. SQL Server 常用关键字