如何设计一个全类型冒泡排序

一.参数

        要实现全类型冒泡排序,函数的参数应该使用void*,表示接受任意类型,我们还要知道要排序数

组的元素个数,使用size_t,由于我们不知道要排序什么类型的数组,如果是一个结构体数组,那该如何

排序,所以我们需要使用者自己写一个比较函数.这样使用者也可以根据自己的想法来选择排序方式.

比如递增排序,递减排序,后面只需调用这个函数,把较大的交换即可,但我们不知道要交换的数据的类

型,所以我们使用指针的方式交换数据,为了能够交换所以的数据类型,我们还需要知道这种类型的大

小,最后这个函数是操作数组,不需要返回值,最后得出

void bubble_sort(void* arr, size_t num, size_t size, int(*comp)(const void* i, const void* j))

        四个参数,第一个接受任意类型的数组,第二个是数组的元素个数,第三个是每个元素的大小,第

四个是一个函数指针,指向一个使用者自己写的比较函数,

二.内部实现

        内部的实现非常简单,就是一个普普通通的冒泡排序,通过使用者自己提供的比较函数,要求这个

函数,传入数组两个数的地址,比如如果是Int类型的数组,我们只需arr+i;就能找到这个数的地址,但由

于我们不知道是什么类型,无法确定地址,但实际上,比如一个Int类型的数组,因为Int是四个字节,所以

我们可以这样表示,

        我们知道指针加上或减去一个整数,它的值与指针的类型有关系,比如int类型的指针加上1,就会

跳过四个字节,char类型的指针加1,则会跳过1个字节,所以我们可以将其转换为char*类型找到地址,

&arr[i]=arr+i=(int*)((char*)arr+i*4)
void bubble_sort(void* arr, size_t num, size_t size, int(*comp)(const void* i, const void* j))
{
	for (int i = 0; i < num - 1; i++)
	{
		for (int j = 0; j < num - 1 - i; j++)
		{
			if (comp((char*)arr + j * size, (char*)arr + (j + 1) * size) > 0)
			{
				swap((char*)arr + j * size, (char*)arr + (j + 1) * size, size);
			}
		}
	}
}

        我们重点看一下是如何对任意类型元素交换位置,

三.内部函数

        从上面我们可以看出,swap这个函数,有三个参数

void swap(char* i, char* j, size_t size);

        接受两个要交换的元素的地址,还有元素的大小,由于我们不知道是什么类型,那该如何交换呢

还是要使用char*类型辅助,char*类型加1,就是移动一个字节,把要交换的元素的地址每个字节都交换

一下不就行了吗

void swap(char* i, char* j, size_t size)
{
	for (int n = 0; n < size; n++)
	{
		char a = *i;
		*i=*j;
		*j = a;
		i++, j++;
	}
}

四.举例

排序数组

        比如我们要使用这个函数递减排序一个整型数组,那我们就把比较函数写成这样

int comp(const void* i, const void* j)
{
	return *(int*)j - *(int*) i;
}

排序结构体

要排序结构体,我们完全可按照我们自己想的方式排序

比如我们定义这个结构体

typedef struct Stu
{
	char name[20];
	int age;
}Stu;

我想要按照年龄从小到大来排序

我就可以把比较函数写成这样

int cmp_stu_age(const void* e1, const void* e2)
{
	return ((Stu*)e1)->age - ((Stu*)e2)->age;
}

我想要从姓名的字母排序

我就可以把比较函数写成这样

int cmp_stu_name(const void* e1, const void* e2)
{
	return strcmp(((Stu*)e1)->name, ((Stu*)e2)->name);
}

想要怎样排序只在于使用者自己写的比较函数,与快排函数qsort类似

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值