C语言——姐带你一步步超详细用冒泡排序法模拟实现 qsort 函数

1.什么是冒泡排序

核心思想:两相邻元素进行比较

排列n个元素,需要排列 n - 1 组(每组解决1个数字),每组排列 n-i-1 次(排列好的数字不再进行交换)。

这里我们移将数组元素升序排列进行解释说明。

第一组:从数组的首元素开始,将首元素和第二个元素进行比较,如果首元素大于第二个元素,将首元素和第二个元素进行交换,反之不换;之后再将第二个元素和第三个元素进行比较,如果第二个元素大于第三个元素,将第二个元素和第三个元素进行交换,反之不换;以此类推,交换了n-1次后,数组的最大元素就放在了数组的最后。

接着进行第二组:与第一组步骤类似,但是因为数组的最大元素放在了数组的最后,所以数组的最后一个元素不用比较,因此我们交换n-2次后,数组的第二大元素就放在了数组的倒数第二个地址中。

以此类推,我们 n-i 组排序时,我们需要交换 n-i-1 次元素,将数组的第 i 大元素放在倒数第 i 个位置中。

当我们进行第 n-1 组排序后,数组的元素将按升序排列。

但是我们需要思考一个问题,当我们还未经过进行 n-1 组排序,数组就已经是按升序排列,如果我们再接着进行比较,代码运行效率未免太过低。因此,我们思考该怎样解决这个问题呢?

我们可以通过在每组排列之前,先假设数组的元素按升序排列,如果这组元素排列时,只要有元素进行交换,我们就否认数组按升序排列,否则,跳出组排列循环。

 

b52ac370ea3a4be08b5427af10363bba.png         0ac6faec296946808dda7c11d238d99d.png

 

但是我们发现,这种代码只能实现一种数组类型的排序,那当我们需要实现多种数组类型的排序时,这种代码就不再适用,那该怎么解决这个问题呢?

2.qsort函数

1.认识 qsort 函数

对数组的任何类型的元素进行排序

头文件<stdlib.h>

4b906dfd76aa4a8aa42c27f9b95f5ac6.png

9bc2ea4d59f946c484c5d469e1b89c61.png

comper函数返回值 大于0,交换位置,等于或小于0,位置不变。

 

2.怎么使用qsort函数     

以排列结构体数组元素为例。

1.创建结构体数组

eb76535ee10542f3bba8ebe1a9938fc6.png

2.使用qsort函数使结构体数组的元素按所需排列的成员进行排序

881aed6f9e614325be4c88de28808ed2.png

3.打印排好序的结构体数组

db749d59d4ee41ac9e3612b91c59e58d.png

 

3. 用冒泡排序法模拟实现 qsort 函数

1.创建结构体数组

2.用自定义array_sort函数将结构体数组的元素按所需排列的成员进行排序

3.2.1 构建自定义array_sort函数,使用两个for循环将数组元素进行冒泡排序。并判断两个元素的所需排列的成员是否满足排序条件,如果不满足,需要将两个元素进行位置互换。用flag判断结构体数组是否已经排好序。

我们不知道结构体数组元素的类型,所以没办法通过指针变量得到所需元素的地址,但是我们有结构体数组首元素的地址 base 和每个元素所占的字节数 size ,所以,我们可以通过将首元素的指针类型强制转换成char* 类型,通过(char*)base + j * size 得到所需元素的地址

86fc0c32802c4a7bbac3fc36fb77a0a9.png

3.2.2.通过回调函数,判断结构体数组的两个元素的所需排列的成员的大小

8f9ec2a9dcc6465b88b7693da2acbf4d.png

3.2.3 如果不满足排列条件,需要将两个元素交换位置。

但是,我们并不知道这两个元素的类型,无法直接交换,但是我们知道每个元素占多少个字节width ,所以,我们可以将两个元素一个字节一个字节的进行交换。这时,我们可以将两个元素的指针类型强制转换为char* 类型。

133e0b84c8e04ceb82021e551f7e658b.png

a418fd393a2044f7bfe8d4abb0b030a2.png

4 打印排好序的结构体数组

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值