函数qsort的使用与冒泡排序模拟实现qsort

目录

一.qsort函数的使用

示例

二.使用冒泡排序模拟实现qsort函数

二.1.冒泡排序

 二.2.模拟实现qsort函数


一.qsort函数的使用

1.

1.qsort函数是用来排序任意数据类型的数组,对其中的元素进行一定规则的排列

2.qsort不返回任何值

3.qsort的第一个参数是一个 void* 指针,指向数组的第一个元素

4.qsort的第二个参数是size_t类型的参数,代表的是数组中元素的个数

5.qsort的第三个参数是size_t类型的参数,代表每个元素的大小,单位是字节,比如int类型就是4个字节,char类型就是1个字节

6.qsort的第四个参数是一个函数指针,指向一个返回值为int参数为两个 const void*的函数,函数的参数分别指向两个元素,如果第一个元素大于第二个元素,就返回一个大于0的值,如果第一个元素小于第二个元素,就返回一个小于0的值,如果第一个元素等于第二个元素,就返回0,该函数用于比较数组中的元素,并且该函数需要我们自己创建。

7.使用qsort时需要包含头文件<stdlib.h>

示例

1.这里,我们想对于int类型的数据比较,将int类型的元素从小到大排列,我们创建了一个函数int_cmp来比较两个int类型的元素,先把两个const void*指针的参数强制类型转化成int*类型的参数,这样再解引用,一次读取四个字节,就可以得到这个int类型的值了,return的是两个int元素相减的值,如果第一个元素大于第二个数,那么返回值一定是大于0的,同理,如果第一个元素小于第二个元素,返回小于0的数,如果第一个元素等于第二个元素,返回0,符合qsort第四个参数的标准。

2.我们依次将参数(数组首元素地址,元素个数,元素大小,比较函数)输入到qosrt中,实现整形类型的排序

3.此函数不止能排列整形数组,可以排列任意类型的数组(整形数组,字符数组,结构体数组..)

只要能够写出判断的函数,就能够对数组进行排序,因为排序的规则是自己制定的,上述代码是对结构体数组按元素中age的从小到大进行排序的例子,年龄小从第二个元素被换到第一个元素。通过比较每个结构体中age的大小实现比较函数age_cmp。

二.使用冒泡排序模拟实现qsort函数

二.1.冒泡排序

1.什么是冒泡排序呢?简单来说就是通过比较数组中两两相邻的元素进行排序。

2.比如,现在有一个如图所示的数组,我们要将其从小到大依次排序,我们先比较第一个和第二个元素,如果第一个元素大于第二个元素,那么我们就将这两个元素的值交换,反正,则保持不变。

 4小于8,所以我们不进行交换,那么再比较第二个元素的第三个元素

 

 8大于3,那么把第二个元素和第三个元素的值互换,依次类推,第一轮比较之后,效果如图所示

 

 那么,到底要进行几轮这样的比较才能够将其排列完成呢?

只需要比较 元素的个数-1轮,即可完全排列好,因为你排列第一轮,就会确定一个最大值在数组的最后,第二轮,会确定一个倒数第二大的数在数组的倒数第二个元素,依次类推,直达排列 元素的个数-1轮,第一个位置因为其它的位置已经都被确定过了,所以无需再比较。

那么,每一轮需要比较几次呢?

第一轮两两比较,需要比较元素的个数-1次,但是第二轮由于数组的最后一个元素已经被确定,不用比较数组的倒数第二个元素和倒数第一个元素,所以第二轮会比第一轮少比较一次。

假如数组有n个元素第i轮排列就需要比较n-i次

现在,让我们用代码实现一个排列元素是int类型数组的冒泡排序。

 

 二.2.模拟实现qsort函数

这是函数最终的样子,看起来十分复杂,但是我们可以将其拆解,让其变得简单。

首先,我们先写出一个冒泡排序的框架,排列num-1轮,排列num-1-i次

然后,我们就需要比较相邻两个元素的大小,但是,我们并不知道它是什么类型的元素,所以我们需要用void*指针来接收数组首元素的地址,再根据接收到的元素个数元素大小进行判断。

void*指针不能直接使用,我们先将其强制转化成char*类型(char*类型每次读取一个字节,每次加减一个字节),这样,第j+1个元素的地址就是(char*)base + j * size,比如,第一个元素的地址就是(char*)base

将相邻两个元素通过比较函数比较,如果返回值大于0,就将两个元素交换

那么,如何交换两个元素呢,我们可以把元素分成一个一个字节,把相邻元素的每个字节都进行交换,那么,每次交换相邻元素,就需要交换size个字节,所以,我们可以通过一个循环来实现

这样,我们就利用冒泡排序成功模拟实现了qsort函数

示例

  • 14
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
冒泡排序和快速排序(qsort)虽然都是常见的排序算法,但它们的工作原理和效率有很大的不同。冒泡排序是一种简单的比较排序算法,而快速排序则是一种高效的分治策略。如果你想了解如何模仿`qsort`实现冒泡排序,其实这不是一个直接的对应,因为`qsort`是基于分治法的高效排序,而冒泡排序更适合教学和理解基本排序原理。 不过,为了满足你的要求,我们可以探讨一下如何用类似`qsort`的方式设计一个冒泡排序的“迭代”版本,虽然这并不是真正意义上的模仿,因为它们在实现上并不相同。 **冒泡排序的简化版(不是真正的`qsort`)**: 1. 定义一个辅助函数,类似于`qsort`的分区过程,但仅用于比较相邻元素并交换: ```c++ void bubbleSortPartition(int arr[], int low, int high) { while (low < high) { if (arr[low] > arr[high]) { std::swap(arr[low], arr[high]); } low++; high--; } } ``` 2. 用递归调用的方式实现冒泡排序: ```c++ void bubbleSortIterative(int arr[], int size) { for (int i = 0; i < size - 1; i++) { bubbleSortPartition(arr, 0, size - 1 - i); } } ``` 这里我们不是直接将整个数组作为一次排序,而是每次缩小待排序范围,直到整个序列有序。 **相关问题--:** 1. 冒泡排序与快速排序的主要区别是什么? 2. 在冒泡排序中,为什么要使用`bubbleSortPartition`函数? 3. 如何评价这种将冒泡排序与`qsort`风格结合的简化版本?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值