冒泡排序(字节交换)

冒泡排序的思想就是相邻元素依次比较,把该元素放在对应的位置,用一个动图来解释:
冒泡排序思想

普通的冒泡排序代码:

void Bubble_sort(int* base, int sz)
{
	for (int i = 0; i < sz - 1; i++)
	{
		for (int j = 0; j < sz - i - 1; j++)
		{
			if (base[j] > base[j + 1])
			{
				int tmp = base[j];
				base[j] = base[j + 1];
				base[j + 1] = tmp;
			}
		}
	}
}

我们对上述代码进行深入的研究,能不能写一个bubble_sort就能排序所有的类型,比如上面的常规冒泡排序,只能排int类型,如果是float,double,struct就又得重新写了
首先给出一个概念,指针类型其实是相当于一个权限,当我解引用的时候能取到内存中多少个字节的内容
因此我们可以通过交换字节来实现交换两个值,我们只需要知道当前类型占几个字节即可,传参的时候多传一个字节大小,上面说到指针类型相当于一个权限,在我们不确定类型的时候但知道字节大小,可以一个字节一个字节的交换,那么强制类型转换为char就可以每次只交换一个字节了。
**由于一开始我也不知道要传什么类型,那么我们可以用void
来接收,但void只能用来接收,不能用来接收,比如voidarr,但arr++这个操作是不允许的,所以在使用的时候要进行强制类型转换**

图解

void Swap(char* buf1, char* buf2, int width)
{
	for (int i = 0; i < width; i++)
	{
		char tmp = *buf1;
		*buf1 = *buf2;
		*buf2 = tmp;
		buf1++, buf2++;
	}
}

int cmp(const void* e1, const void* e2)
{
	return *(int*)e1 - *(int*)e2;//一次性取了四个字节
}

void bubble_sort(void* base, size_t sz,size_t width,int(*cmp)(const void*e1,const void*e2))
{
	for (int i = 0; i < sz - 1; i++)
	{
		for (int j = 0; j < sz - 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);
			}
		}
	}
}

接下来可以来看看内存的变换:
没有交换之前

交换之后

posted @ 2023-08-24 22:22  Hayaizo  阅读(55)  评论(0)    收藏  举报