库函数《qsort》的模拟实现,原来如此简单

您所在的位置:网站首页 c语言排序函数怎么写 库函数《qsort》的模拟实现,原来如此简单

库函数《qsort》的模拟实现,原来如此简单

2024-06-21 01:54| 来源: 网络整理| 查看: 265

库函数《qsort》的模拟实现 前言一、qsort函数二、qsort函数实现思路1. 底层原理2. 函数传参1). 第一个参数2). 第二个参数3). 第三个参数4). 第四个参数 三、局部函数实现四、全部代码汇集五、总结

前言

我们在上一篇博客讲解了库函数qsort的使用,今天我为大家带来qsort的模拟实现。上一篇博客这个库函数的阅读链接:一篇文章看懂《qsort》快排的用法

其实有人会问,我明明已经掌握了库函数qsort的使用方法,为何还要去写模拟实现,其实啊,学好一个东西,不仅仅只是会用就可以,如果我们能更深层次的去探索这个函数是怎么实现的,我相信,这其中的乐趣,不一般。。。

仅以此篇文章作为我学习的见证,希望能够各位带来一定的帮助,谢谢。文章若有不妥之处,欢迎指点。这是一个共同进步的平台!!!

一、qsort函数

我们先看看qsort函数的使用:

#include #include int cmp_int(const void* e1, const void* e2) { //e1-e2,得到的是升序 return *(int*)e1 - *(int*)e2; } int main() { int arr[10] = { 2,3,1,4,5,6,7,9,8,10 }; int sz = sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_int); int i = 0; for (i = 0; i int j = 0; for (j = 0; j 2,1,4,5,6,3};

我们以这个数组为例,我们想想,如果我们要排一个升序的数组,只需要我们传递给(cmp_int)函数的两个参数相减为正数,上一篇博客提到了口诀“左减右为升序,反之则降”,即就是e1 - e2 大于0 ,也就是e1>e2了。 注:函数参数(const void* e1,const void* e2)

知道了其中原理,就好实现了呗,if语句判断,如果(cmp_int)函数的放回值大于0,我们就交换一下两个数。

void my_sort(void* base, size_t sz, size_t width, int (*cmp)(void*, void*)) { //函数里面实则还是冒泡排序 int i = 0; for (i = 0; i //进行判断和交换 if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0) { //此处函数传参的时,并非只需要传递两个需要交换的数据,还有数据的大小,即就是字节数 //例如是整体数据交换,而Swap函数,其实函数里面需要循环4次才行,因为是4个字节的数据嘛 Exch((char*)base + j * width, (char*)base + (j + 1) * width, width); } } } }

随着j的增加,我们比较的数据也一个个的往后移,特别注意(char*) base + j * width,我们在使用base时,必须先要进行强制类型转换,这样再进行加减操作才可以。因为 base的类型是 void * 类型,没有具体的大小。强制类型转换后,再加上j*width个字节,这样就能找到数组中一个个的元素。

接下来就是函数Exch的实现,这个函数就是交换两个数的位置用的,(exchange)。上面的if语句如果成立,我们就调用函数Exch,去交换两个数的位置,传参的话,跟if语句里面的参数一样的,毋庸置疑。只是我们在传参的时候,还需要传第三个参数width,因为我们调用函数Exch后,函数里面一次交换,只能交换1个字节的内容。有小伙伴就会问,我一次直接交换4个字节的内容,这不是简单的多了嘛。。。。 对于整形数组,一次直接交换4个字节的内容,当然简单了,但是我们需要交换其他数据类型的时候呢,难道还要重新写一遍my_sort吗??是吧,所以,1个字节慢慢交换,循环width次就行,这样写出来的函数,才是通用的。 Exch函数的实现

void Exch(char* cmp1, char* cmp2, size_t width) { int i = 0; for (i = 0; i return *(int*)e2 - *(int*)e1; } void Exch(char* cmp1, char* cmp2, size_t width) { int i = 0; for (i = 0; i //函数里面实则还是冒泡排序 int i = 0; for (i = 0; i //进行判断和交换 if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0) { //此处函数传参的时,并非只需要传递两个需要交换的数据,还有数据的大小,即就是字节数 //例如是整体数据交换,而Swap函数,其实函数里面需要循环4次才行,因为是4个字节的数据嘛 Exch((char*)base + j * width, (char*)base + (j + 1) * width, width); } } } } int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int sz = sizeof(arr) / sizeof(arr[0]); my_sort(arr, sz, sizeof(arr[0]), cmp_int); int i = 0; for (i = 0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3