C语言qsort函数的使用,及自己实现的qsort函数

目录

 一,qsort函数的介绍

         二,实例,用qsort函数,实现冒泡排序,把降序改为升序

         三,用qsort函数,排序结构体变量

       四,自己实现一个qsort函数,用冒泡思维写

 1,分析判断两个数据是否需要交换

 2,如何交换,

      五,自己实现的qsort函数,的整体使用

一,qsort函数的介绍

void qsort(void* base, size_t num, size_t width, int(*cmp)(const void* e1, const void* e2))

首先它是一个排序函数!能量巨大,可以排序任意类型的数据,整型,数组,结构体,字符等

qsort函数一共有四个参数:

1,void* base:是要排序的数据的起始位置,这是一个指针,返回类型为空的,void类型,必须是void*,不能擅作主张修改,改的是base,起始地址,用自己想用的。

2,size_t num:是待排序的数据元素的个数,传过去一个整型

3,size_t width:是待排序的数据元素的大小,单位是字节。传过去一个整型

4,int(*cmp)(const void* e1, const void* e2)这是函数指针,比较函数,可以自己去设计,具体怎么比较,看题目的具体安排。它的规定是,e1<e2 返回<0,e1=e2返回=0,e1>e2返回>0。

这样才能比较,这是这个函数的自有规定,按照这个规定来设计就行。注意e1是你要比较的元素的一个地址,e2是另一个元素的地址。

二,实例,用qsort函数,实现冒泡排序,把降序改为升序

1,代码逻辑简单,重点是cmp1函数

 解析:两个元素地址传过来,是void*类型的,根本不可以进行加减操作,一定要把它强制类型转换为int*类型的,才可以进行加减操作。

这样,两个整型元素相减,返回值要么是>0,要么是=0,要么是<0,符合函数的规定。

然后,按照相减之后的值排序,例如 9-5=4  9-3=6,直接推出,9比5大。而结果的6比4大,间接推出5又比3大,所以,3,5,9排序成功,9在最后面,依次类推,遍历了各种情况,排序为由小到大的升序。

 想要把升序,改为降序也可以,把return 的p1和p2调换即可。我想不用过多演示了吧。

三,用qsort函数,排序结构体变量

大致流程和上述例子一样,我把解析部分写在注释里面了,核心点是指针的强制类型转换,把void*类型转换为结构体指针类型,进行运算比较。

四,自己实现一个qsort函数,用冒泡思维写

 1,分析判断两个数据是否需要交换

4个参数是固定的,循环的趟数是固定的,需要修改的是,判断两个数据,是否需要交换,以及怎么交换。

cmp函数和上述的一样,为什么if语句里面是,强制类型转换为char*呢?

因为在字节这个单位里面,char类型的最小,是一个字节,把整型4个字节强制类型转换为一个字节,然后地址加上宽度*j,就相当于跨过了一个整型,到了下一个整型的地址。

这绝对不是多此一举,下次如果是浮点型,结构体类型,就跨越 宽度*j,这种写法是通用方式。以此判断出两个数据的大小,到底是否需要交换。

精髓:要运算的是整型,但是转换为(char*)base+size*j,表示了一个整型地址,给cmp函数传过去,接收的是void*类型,无法加减,又得强制类型转换为int*类型。。。。。。。。。。。看到这要开骂了?  真不是画蛇添足。。

真得需要仔细琢磨,因为函数强大,以后可以用于各种情况,所以每一步的操作就得考虑其余情况的使用,这是通用版本。不能想当然的,就都使用整型指针不是最方便?那样这题是方便了,下次换个类型就一点没用了。。。。。。。

return 返回正数,说明前面的数大,需要交换。同理可知。

 2,如何交换,

 传参,传过来两个数据的地址,和宽度大小size,具体多少个字节。循环几次由字节数控制。强制类型转换为char*是一个字节,整型是4个字节,两个数据交换就需要4次,这是一个字节一个字节是交换,4次之后,就是整体交换完毕了。

看图吧,1个整型四个字节,1和1交换,2和2交换,3和3交换,4和4交换。这样具体一个整型就交换完毕了,以后要是浮点型,结构体,也可以这样,无非是循环多一点。

((char*)p1 + i)就是第一个数据的起始地址,((char*)p2 + i)是第二个数据的起始地址。i 每走一步,就是挪一个字节。

 五,自己实现的qsort函数,的整体使用

 

 整体没毛病,就是有点绕的慌

要是想要修改,排降序,只需要改动cmp函数那里就ok了,结构体排序也可以,但要记住传参过去,要强制类型转换。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值