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

前言

我们知道,qsort的底层排序代码原理是快排,但我们今天利用更简单的冒泡排序实现qsort函数

一、冒泡函数的原理

以上参考我曾经写的一篇博客
链接:https://blog.csdn.net/Tlzns/article/details/128406959?spm=1001.2014.3001.5501

二、qsort函数分析

我们要用冒泡模拟一个qsort函数,在我们已经熟悉冒泡的情况下,分析qsort的参数,进行模拟
qsort有四个形参,分别是待排数组的首地址,数组元素个数,以及数组单个元素的字节大小,还有一个比较函数

在这里插入图片描述
由于我们得到的是void*类型的指针,该指针不能通过解引用,所以如何传参比较函数中元素的大小,以及如何将函数中的元素进行交换是我们需要解决的问题

三、实现过程

下面是冒泡排序基本框架

void Bubble_qsort(void* base, size_t num, size_t width, int (*cmp)(const void* p1, const void* p2))
{
	int i = 0;
	for (i = 0; i < num - 1, i++)
	{
		int flag = 1int j = 0;
		for (j = 0; j < num - 1 - i; j++)
		{
			if (cmp > 0)//调用比较函数获得的返回值来判断是否普交换值
			{
				swap();
				flag = 0;
			}
		}
		if (flag == 1)
		{
			break;
		}
	}
}

关于冒泡详情可以查看我之前写的关于冒泡的一篇文章
链接:https://blog.csdn.net/Tlzns/article/details/128406959

我们不难看出,有待我们解决的问题有:
1.在viod类型指针的前提下如何给比较函数cmp传参获得正确的返回值
2.在viod
类型指针的前提下如何交换需要交换的两个值

进一步观察qsort获得的形参,有待排数据元素个数num,单个元素字节宽度width
作为qsort函数的作者,并不知道未来使用者用来排序什么类型
但我们可以默认获得的数据类型为char,获得该元素每个数据的起始地址
我们在调用cmp函数时可以进行以下操作

cmp((char*)base + j * width, (char*)base + (j + 1) * width)

我们以int类型的数组为例
在这里插入图片描述
我们将图中的数据首地址传给比较函数,通过函数使用者获得对应的返回值 判断是否需要交换
我们解决了如何调用cmp函数,接下来需要解决如何交换对应的元素
我们知道char类型的数据char类型的数据在内存中占一个字节,short类型占两个字节,int 占四个字节
而现在我们不能通过解引用的方式创建临时变量直接交换对应的值,我们可以将元素数据中的每个字节都进行交换
从而最终交换了两个元素
在这里插入图片描述

swap(char* p1, char* p2,int width)
{
	while (width)
	{
		char tmp = *p1;
		*p1 = *p2;
		*p2 = tmp;
		p1++;
		p2++;
		width--;
	}
}

实现代码

swap(char* p1, char* p2,int width)
{
	while (width)
	{
		char tmp = *p1;
		*p1 = *p2;
		*p2 = tmp;
		p1++;
		p2++;
		width--;
	}
}


void Bubble_qsort(void* base, size_t num, size_t width,int (*cmp)(const void *p1,const void *p2))
{
	size_t i = 0;
	for (i = 0; i < num-1; i++)
	{
		int j = 0;
		int flag = 1;
		for (j = 0; j < num - 1 - i; j++)
		{
			if (cmp((char*)base + j * width, (char*)base + (j + 1) * width))
			{
				swap((char*)base + j * width, (char*)base + (j + 1) * width,width);
				flag = 0;
			}
		}
		if (flag == 1)
		{
			break;
		}
	}
}

以上就是qsort函数用冒泡算法的模拟实现

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值