本文介绍: 因为char*类型可以更细致的比较,如果我们比较的是int类型数据,与下一元素相距4个字节,而char*一次跳不了那么大的距离,所以我们需要加1*size(即数据类型大小)。这样不管需要进行什么类型的数据的比较,我们只要在参数中给出数据的类型大小,就能直接比较,使这个函数更加通用。我们自己定义一个cmp_int函数,调用它的指针的形参名为cmpcmp用来判断两个元素大小。如果我们想对任何数据进行排序我们可以发现排序的趟数是固定的,我们只需要对比较大小的方式进行改造即可

如图,这是比较常见冒泡排序,不过只能对整形数据进行排序本篇博文主要介绍如何模拟qsort函数实现冒泡排序对任何数据的排序。  

如果我们想对任何数据进行排序,我们可以发现排序的趟数是固定的,我们只需要对比较大小的方式进行改造即可。

我们模仿qsort函数,并且约定如下

改造后的代码如下

void swap(char* buf1,char* buf2,size_t size)
{
	int i= 0;
	for (i = 0; i < size; i++)
	{
		char tmp = *buf1;
		*buf1 = *buf2;
		*buf2 = tmp;
		buf1++;
		buf2++;
	}
}

void bubble_sort(void* base, size_t num,size_t size,int (*cmp)(const void* e1,const void* e2))
{
	int i = 0;
	for (i = 0; i < num - 1; i++)
	{
		int j = 0;
		for (j = 0; j < num - 1 - i; j++)
		{
			if (cmp((char*)base+j*size,(char*)base+(j+1)*size )>0)
			{ 
				swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
			}
		}
	}
}

int cmp_int(const void* e1, const void* e2)
{
	return *(int*)e1 - *(int*)e2;
}

void test1()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	print_arr(arr, sz);
	bubble_sort(arr, sz,sizeof(arr[0]), cmp_int);
	print_arr(arr, sz);
}

整体分析:bubble_sort函数的第一个参数void*类型,是因为我们要比较的数据类型不确定。剩下的参数均是模仿qsort函数的,详细见上一篇博文。我们自己定义一个cmp_int函数,调用它的指针的形参名为cmp,cmp用来判断两个元素的大小。在上一篇博文中,我们说qsort使用来进行升序排序的,其实我们也可以进行降序排序,只需要将cmp()&gt;0改成cmp()<0即可。swap函数是我们自己定义的常见交换函数。

cmp函数分析base是首元素地址,因为他是void*类型,无法直接解引用,我们需要进行强制类型转换,不过为什么转换成char*类型呢?因为char*类型可以更细致的比较,如果我们比较的是int类型的数据,与下一元素相距4个字节,而char*一次跳不了那么大的距离,所以我们需要加1*size(即数据类型的大小)。这样不管需要进行什么类型的数据的比较,我们只要在参数中给出数据的类型大小,就能直接比较,使这个函数更加通用。

原文地址:https://blog.csdn.net/qinjh_/article/details/134739021

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_21340.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注