【排序】什么都能排的C语言qsort排序详解【超详细的宝藏级别教程】深度理解qsort排序
【排序】什么都能排的C语言qsort排序详解【超详细的宝藏级别教程】深度理解qsort排序
作者: @小小Programmer
这是我的主页:@小小Programmer
在食用这篇博客之前,博主在这里介绍一下其它高质量的编程学习栏目:
数据结构专栏:数据结构 这里包含了博主很多的数据结构学习上的总结,每一篇都是超级用心编写的,有兴趣的伙伴们都支持一下吧!
算法专栏:算法 这里可以说是博主的刷题历程,里面总结了一些经典的力扣上的题目,和算法实现的总结,对考试和竞赛都是很有帮助的!
先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说是一种非常重要的动力。看完之后别忘记关注我哦!️️️
本篇建议收藏后食用~
博主之前,也发表过一篇有关排序的博客,里面包含了九大排序的详细剖析,也是干货满满的宝藏噢,需要的伙伴可以通过传送门食用~【排序】万字九大排序宝藏汇总 轻松拿下九大排序算法【带动画】 (包含超详细的解释和注释)
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排序的更多相关文章
- C语言内存对齐详解(2)
接上一篇:C语言内存对齐详解(1) VC对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式.VC 中提供了#pr ...
- c语言贪吃蛇详解3.让蛇动起来
c语言贪吃蛇详解3.让蛇动起来 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 上次 ...
- c语言贪吃蛇详解-2.画出蛇
c语言贪吃蛇详解-2.画出蛇 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 蛇的身 ...
- 全网最详细的Hadoop HA集群启动后,两个namenode都是active的解决办法(图文详解)
不多说,直接上干货! 这个问题,跟 全网最详细的Hadoop HA集群启动后,两个namenode都是standby的解决办法(图文详解) 是大同小异. 欢迎大家,加入我的微信公众号:大数据躺过的坑 ...
- C语言文件操作函数大全(超详细)
C语言文件操作函数大全(超详细) 作者: 字体:[增加 减小] 类型:转载 本篇文章是对C语言中的文件操作函数进行了详细的总结分析,需要的朋友参考下 fopen(打开文件)相关函数 open,fc ...
- C语言memset函数详解
C语言memset函数详解 memset() 的作用:在一段内存块中填充某个给定的值,通常用于数组初始化与数组清零. 它是直接操作内存空间,mem即“内存”(memory)的意思.该函数的原型为: # ...
- C语言中字符串详解
C语言中字符串详解 字符串时是C语言中非常重要的部分,我们从字符串的性质和字符串的创建.程序中字符串的输入输出和字符串的操作来对字符串进行详细的解析. 什么是字符串? C语言本身没有内置的字符串类型, ...
- C语言之预处理详解
C语言之预处理详解 纲要: 预定义符号 #define #define定义标识符 #define定义宏 #define的替换规则 #与## 几点注意#undef 带副作用的宏参数 宏和函数的对比 命名 ...
- C语言内存对齐详解(3)
接上一篇:C语言内存对齐详解(2) 在minix的stdarg.h文件中,定义了如下一个宏: /* Amount of space required in an argument list for a ...
- c语言贪吃蛇详解1.画出地图
c语言贪吃蛇详解-1.画出地图 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 首先 ...
随机推荐
- The 18th Zhejiang Provincial Collegiate Programming Contest 补题记录(ACFGJLM)
补题链接:Here A. League of Legends 签到题,求和判断即可 ll suma, sumb; void solve() { ll x; for (int i = 1; i < ...
- java基础(3)--pulic class与class的区别
1.一个类前面的public是可有可无的2.如果一个类使用 public 修饰,则文件名必须与类名一致3.如果一个类前面没有使用public修饰,则文件名可以与类名不一致.当编译成功后会生成对应类名的 ...
- offline RL | ABM:从 offline dataset 的好 transition 提取 prior policy
ICLR 2020,6 6 6. 材料: 论文题目:Keep Doing What Worked: Behavior Modelling Priors for Offline Reinforcemen ...
- 如何与chatgpt共存
作为程序员,专注于创造性劳动,而把重复性劳动任务交给chatgpt,要成为 需求 和 chatgpt的桥梁. 人工智能比如chatgpt越来越强,提问能力是人类的天赋,提问能力更为重要.
- AI伴侣下载
总结 现在网页上很多下载的AI伴侣下载下来都会有些问题或者不能用,如下链接下载的AI伴侣亲测可以使用! (连接后会提示更新,博主没有选择更新,如有需要也可以更新) https://mit-ai2-co ...
- 【Git】Git与Repo入门
[来源]https://www.cnblogs.com/angeldevil/archive/2013/11/26/3238470.html
- Linux-文件权限-rwx-chmod
- [转帖]在 Linux 上以 All-in-One 模式安装 KubeSphere
https://www.kubesphere.io/zh/docs/v3.4/quick-start/all-in-one-on-linux/ 对于刚接触 KubeSphere 并想快速上手该容器平台 ...
- [转帖]记druid 连接池没满,但超时问题 GetConnectionTimeoutException active 5, maxActive 100
记druid 连接池没满,但超时问题 GetConnectionTimeoutException active 5, maxActive 100 问题说明 线上服务突然出现报错,通过日志查找发现是因为 ...
- [转帖]Datadog 能成为最大的云监控厂商吗
https://xie.infoq.cn/article/901cfd6b284e3e103ac70aeb3 作者:睿象云 2021-03-25 本文字数:2256 字 阅读完需:约 7 分钟 D ...

