创建一个适用所有类型的冒泡排序函数

前言

相信大家在自己创建排序函数时,每次写出的算法只适用于单个类型,极不方便。
今天为大家带来全类型的冒泡排序函数的编写,这样既可以一步到位,又可以在同学,朋友面前装个杯,不可谓不香。

整形冒泡排序代码

void buddle_sort(int* arr,int sz)
{
	for (int i = 0; i < sz;i++)
	{
		for (int u = 0; u < sz - i-1; u++)
		{
			if (arr[u] > arr[u + 1])
			{
				int tmp = arr[u];
				arr[u] = arr[u + 1];
				arr[u + 1] = tmp;
			}
		}
	}
}

这个就是最普通的整形冒泡排序代码,现在我们要将其改写为全类型通用,我们从零开始可能有点困难,我们可以借鉴一下在c语言的库函数中qsort函数需要什么样的参数。

这时有人可能会说,那直接用qsort函数不就行了吗,确实,在日常使用时确实可以直接使用qsort,但是自己从零开始模拟一个qsort函数的实现,不觉得很有成就感吗。

qsort解读

在这里插入图片描述
这里我们能发现qsort函数需要的参数:
void* base这个就和我们整形的int* base不同,
这里需要补充一下,void*base可以存放所有类型的指针,相当于一个垃圾桶。
但是使用时不能解引用,所以需要配合强制类型转换,这个之后我们会使用到的。
size_t num看得出来是整个数组的元素个数,和我们的整形排序函数相同。
size_t size这个是数组中每个元素的字节大小,这个的作用在之后模拟中会详解。
接下来就是最令人难以理解的int(*compare)(const void*,const void*)
大家都能看出来这是一个函数指针,但是它的作用却匪夷所思
这里我们看一下官方的演示:

int compareMyType (const void * a, const void * b)
{
  if ( *(MyType*)a <  *(MyType*)b ) return -1;
  if ( *(MyType*)a == *(MyType*)b ) return 0;
  if ( *(MyType*)a >  *(MyType*)b ) return 1;
}

这个代码看的出来这个compare是作为一个比较方法存在的,有以下作用:
1:确定需要排序的元素类型
2:确定是正序还是倒序。

qsort的使用

#include<stdio.h>
#include<stdlib.h>
//qsort 结构体使用
struct worker
{
	char name[10];
	int age;
};
int compare(const void* e1, const void* e2)//比较函数,需要返回整形0/1
{
	return strcmp(((struct worker*)e1)->name,((struct worker*)e2)->name);
//对名字进行比较排序
}
int main()
{
	struct worker man[3] = {
		{"zhangwei",30},
		{"sunzi",20},
		{"shabi",40},
	};
	qsort(man,sizeof(man) / sizeof(man[1]),sizeof(man[1]),compare);
	for (int i = 0; i < 3; i++)
	{
		printf("%s  ", (man + i)->name);
		printf("%d\n", (man + i)->age);
	}
	return 0;
}	

这里是使用qsort,进行对结构体中的名字进行比较排序,这里我们能清晰的了解到了compare函数的作用:为qsort确定了比较类型和比较方法。

仿写

按照我的讲解思路,先带大家进行对qsort的模仿,最后在编写中带大家明确讲解各个部分的各个作用,最后达到理解的目的

最后的目的是为了实现对int arr[10] = { 1,5,4,8,6,3,9,7,13,10 };排序。

参数的仿写

void buddle_sort(void* arr,//函数部分
	unsigned int sz,
	unsigned int wirth,
	int(*compare)(const void*,const void*)

函数部分需要以下的参数。这个时候我们在主函数中对这个函数进行传参。

int main()
{
	int arr[10] = { 1,5,4,8,6,3,9,7,13,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	buddle_sort(arr, sz, sizeof(arr[0]), compare);
}

这样就完成了对传参以及函数部分的编写。

compare函数的编写

现在我们就来为函数来编写compare函数。
让我们再来明确一下目的
1:确定比较的类型
2:确定正序还是倒序

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

因为void*使用时无法解引用,而我们的数组int arr[10]是整形数组,
所以对e1和e2进行强制类型转换,在进行解引用即可。

buddle_sort的编写

最开始就是对原冒泡函数的基本思想:

void buddle_sort(void* arr,
	unsigned int sz,
	unsigned int wirth,
	int(*compare)(const void*,const void*)
				)
{
	for (int i = 0; i < sz; i++)
	{
		for (int u = 0; u < sz - i - 1; u++)
		{
			if()
			}

		}

	}
}

先是一个最普通的循环嵌套,接下来最重要的就是
if中的条件了
还记得前面我们写的compare函数吗,此时此刻正是它发挥作用的时候,但是写法却是个大问题。

此时此刻我们需要实现
arr[1]比较arr[2]->
arr[2]比较arr[3]->
arr[3]比较arr[4]…………
就是说我们需要给compare传递的是arr[i],arr[i+1]
compare(arr[i],arr[i+1]) 这个就是正确的吗?
还记得这个arr现在是void类型的指针吗
所以说指针的运算无法进行
现在让我们回头看函数的参数unsigned int wirth
我们特意传了每个元素的大小,这个时候正是它排上用场的时候
提问:哪个指针类型,搭配上每个元素的大小通过运算就能实现对每个字节的改变和调用?
答案正是char*—因为它进行运算时以每个字节为运算量。

所以这里就能有答案了

for (int i = 0; i < sz; i++)
	{
		for (int u = 0; u < sz - i - 1; u++)
		{
			if (compare((char*)arr+wirth*u,
			(char*)arr + wirth*(u+1))>0)
			{
				
				);
			}

		}

	}

将每个元素的指针传过去后与compare函数中
return *(int*)e1 - *(int*)e2;相匹配
将指针转换为int类型,重新获得访问权限,从而实现整个元素的比较。

exchange的编写

if的条件编写完了,接下来距离整个函数的完成只剩下最后一步了——交换函数的编写。
有了每个元素的大小,有了需要交换的元素的指针,接下来就很轻松就可以解决了

void exchange(char* z,char*p,int wirth)
{
	for (int i = 0; i < wirth; i++)
	{
		int tmp = *z;
		*z = *p;
		*p = tmp;
		z++;
		p++;
	}
}

整体代码

#include<stdio.h>
void exchange(char* z,char*p,int wirth)
{
	for (int i = 0; i < wirth; i++)
	{
		int tmp = *z;
		*z = *p;
		*p = tmp;
		z++;
		p++;
	}
}
void buddle_sort(void* arr,
	unsigned int sz,
	unsigned int wirth,
	int(*compare)(const void*,const void*)
				)
{
	for (int i = 0; i < sz; i++)
	{
		for (int u = 0; u < sz - i - 1; u++)
		{
			if (compare((char*)arr+wirth*u,
				(char*)arr + wirth*(u+1))>0)
			{
				exchange((char*)arr + wirth * u,
					(char*)arr + wirth * (u + 1),
					wirth
				);
			}

		}

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

int main()
{
	int arr[10] = { 1,5,4,8,6,3,9,7,13,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	buddle_sort(arr, sz, sizeof(arr[0]), compare);
	for (int i = 0; i < 10; i++)
	{
		printf("%d\n", arr[i]);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 当然,我很乐意帮您写一个C语言冒泡排序的代码。以下是一份示例代码: ```c #include <stdio.h> void bubble_sort(int arr[], int n); int main() { int arr[] = {5, 2, 8, 3, 1, 9}; int n = sizeof(arr) / sizeof(arr[0]); bubble_sort(arr, n); printf("Sorted array: "); for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } printf("\n"); return 0; } void bubble_sort(int arr[], int n) { int temp; for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - i - 1; j++) { if (arr[j] > arr[j+1]) { temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } } ``` 这段代码中,我们定义了一个名为 `bubble_sort` 的函数,它使用冒泡排序算法将一个整型数组进行排序。在 `main` 函数中,我们定义了一个数组 `arr`,并对其调用 `bubble_sort` 函数,最后输出结果。 希望您满意这份冒泡排序的代码! ### 回答2: 冒泡排序是一种简单且常用的排序算法。它通过不断比较相邻元素的大小并交换位置,使得较大的元素逐渐从低位移动到高位,从而实现排序的目的。 以下是用C语言实现冒泡排序的代码: ```c #include <stdio.h> void bubbleSort(int arr[], int n) { for (int i = 0; i < n-1; i++) { for (int j = 0; j < n-i-1; j++) { if (arr[j] > arr[j+1]) { // 交换arr[j]和arr[j+1]的位置 int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } } int main() { int arr[] = {64, 34, 25, 12, 22, 11, 90}; int n = sizeof(arr) / sizeof(arr[0]); printf("排序前的数组:"); for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } bubbleSort(arr, n); printf("\n排序后的数组:"); for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } return 0; } ``` 此代码中的`bubbleSort`函数用于实现冒泡排序。它使用了两层嵌套的循环,外层循环控制需要比较的轮数,内层循环用于比较相邻元素并进行交换。`main`函数则用于测试排序功能,创建一个整型数组并打印排序前后的结果。 上述代码运行结果为: ``` 排序前的数组:64 34 25 12 22 11 90 排序后的数组:11 12 22 25 34 64 90 ``` 以上就是用C语言编写冒泡排序的示例代码。冒泡排序虽然简单,但是当数组规模较大时效率较低,因此在实际应用中一般使用更优秀的排序算法。 ### 回答3: 冒泡排序是一种简单的排序算法,通过重复比较相邻的两个元素并交换位置来进行排序。 下面是一个用C语言编写的冒泡排序的示例代码: ```c #include<stdio.h> void bubbleSort(int arr[], int n) { int i, j; for (i = 0; i < n-1; i++) { for (j = 0; j < n-i-1; j++) { if (arr[j] > arr[j+1]) { // 交换相邻两个元素的位置 int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } } int main() { int arr[] = {64, 34, 25, 12, 22, 11, 90}; int n = sizeof(arr) / sizeof(arr[0]); bubbleSort(arr, n); printf("排序后的数组: \n"); for (int i=0; i < n; i++) { printf("%d ", arr[i]); } return 0; } ``` 在上面的代码中,我们定义了一个`bubbleSort`函数,它接受一个整数数组和数组的大小作为参数。内部使用两个循环嵌套的方式来比较和交换相邻的元素,直到全部元素都有序排列。然后,我们在`main`函数中定义了一个示例数组,并将其传递给`bubbleSort`函数进行排序。最后,我们通过循环打印已排序的数组。 以上是一个基本的冒泡排序的实现。虽然冒泡排序算法简单易懂,但其时间复杂度较高,不适用于大规模数据的排序。在实际应用中,更常用的算法是快速排序、归并排序等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想学c啊啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值