话不多说,直接上代码

 
 //模仿qsort实现一个冒泡排序的通用算法 
  //模仿qsort实现一个冒泡排序的通用算法 
   //模仿qsort实现一个冒泡排序的通用算法 
    //模仿qsort实现一个冒泡排序的通用算法 
#include<stdio.h>
#include<stdlib.h>
//交换函数
//笔记:接收的是base里面元素的数据 ,通过 
void Swap(char*buf1,char*buf2,int width)
{
	int i =0;
	for(i=0;i<width;i++)
	{
		char tmp=*buf1;
		*buf1=*buf2;
		*buf2=tmp;
		buf1++;
		buf2++;//++的原因是通过在字节中进行转换,1个字节数据转换过后,该第二个字节数据进行转换 
		
	}
}
 
 
void bubble_sort(void*base,int sz,int width,int (*cmp)(const void*e1,const void * e2))//base代表第一个对象地址 ,sz代表元素个数,width代表一个元素多大 ,cmp依旧是比较函数 
//至于这里cmp里面e1和e2为什么要加void 和const ,因为只是比较大小而不是改变数值,const是为了更安全 
{
	
	//下面的循环与冒泡排序一致 
	 for(int i =0;i<sz-1;i++)
	 {
	 	for(int j;j<sz-1-i;j++)
	 	{
	 		//对元素进行比较
	 		//笔记:由于void类型指针不能进行加减操作,只能强制转换成其他类型如:int,char
			 //用char*的原因:1.我自己的感觉:这里引用的char*的原因是在不确定base里的元素是什么类型的情况下,char字符型是比较合适的 
			 //b站弹幕看到的原因:由于char*所占字节为1,用char*加 4刚好可以跳到下一个 元素地址,而换成int*或其他的话就不能准确跳到下一个位置 
			 if(cmp((char*)base+j*width,(char*)base+(j+1)*width)>0) //两个元素的地址 
			 {
			 	//交换 
			 	Swap((char*)base+j*width , (char*)base+(j+1)*width , width);
			 }
		 }
	  } 
}
int print(int arr[],int sz)       //输出函数 
{ 
	for(int i =0;i<sz;i++)
	{
		printf("%d ",arr[i]);
	}
	printf("\n");
}
 
int cmp_int(const void*e1,const void*e2)   
{
	return *(int*)e1 - *(int*)e2 ;//通过两个参数的比较大小进行排序 
}
 
 
void test_bubble()
{
	
	int arr[10]={9,8,7,6,5,4,3,2,1,0};
	int sz=sizeof(arr)/sizeof (arr[0]) ;
	print(arr,sz); 
	bubble_sort(arr,sz,sizeof(arr[0]),cmp_int);
	print(arr,sz); 
	
}
 
 
int main()
{
	test_bubble();
	return 0;
 
 } 
 
 

笔记都在代码行中,此文章是看完后第二天记得,大概内容记不清了,等到复习的时候再逐个在回复栏中补充,下面把记在本子上的内容用画图的方式画出来,是关于swap交换函数里面的知识点,注意,此交换不是直接交换元素数值,而是把字节一个一个的交换

用冒泡排序法模仿qsort进行排序(b站鹏哥观看笔记)_数据转换

假设两个4字节里装这些东西,分别用buf1与buf2指向第一个元素,然后通过for循环,buf1与buf2指针分别后移指向后面的元素,把后面的元素一个一个进行交换结束。

void Swap(char*buf1,char*buf2,int width)
{
	int i =0;
	for(i=0;i<width;i++)
	{
		char tmp=*buf1;
		*buf1=*buf2;
		*buf2=tmp;
		buf1++;
		buf2++;//++的原因是通过在字节中进行转换,1个字节数据转换过后,该第二个字节数据进行转换 
		
	}
}