模拟实现qsort

在模拟实现qsort函数之前,我们先来浅浅了解一下qsort函数

void qsort (void* base, size_t num, size_t size,
           int (*compar)(const void e1*,const void e2*))

base 起始地址

num 元素个数

size 元素大小

compar 比较函数

e1 元素1

e2元素2

返回值 含义
<0 e1
=0 e1=e2
>0 e1>e2

与冒泡排序做对比

//冒泡排序
#include 
void bubble_sort(int arr[], int sz)
{
	int i = 0;

for (i = 0; i  arr[j +1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;

			}
		}
	}

}
void print(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
}
int main()
{
	int i = 0;
	int arr[10] = { 10,9,8,7,6,5,4,3,2,1 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr,sz);
	print(arr, sz);
	return 0;
}
	

由此可见,冒泡函数只需起止地址和元素个数即可,过度具体化,只能排序整形数组。

再来康康qsort函数

用qsort给数组进行排序

#include 
#include 
int cmp(const void* e1, const void* e2)
{
	return *(int*)e1 - *(int*)e2;//void*类型的指针不能解引用,所以需强制类型转化为int*
}
int main(){

int i = 0;
	int arr[10] = { 10,9,8,7,6,5,4,3,2,1 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), cmp);
	for (i = 0; i < sz; i++)
	{
		printf("%d", arr[i]);
	}
return 0;
}

用qsort函数对结构体进行排序

//按年龄排
#include 
#include 
struct stu {
	char name[10];
	int age;
	double score;
};
int cmp(const void* e1, const void* e2)
{
	return ((struct stu*)e1)->age - ((struct stu*)e2)->age;
}
int main()
{
	struct stu s[3] = { { "zhangsan",10,98},{"lisi",20,99},{"wangwu",25,100}};
	int sz = sizeof(s) / sizeof(s[0]);
	qsort(s, sz, sizeof(s[0]), cmp);

	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%s  %d   %.2lf\n", s[i].name, s[i].age, s[i].score);
	}
	
	return 0;
}


因此 我们可以看出在使用qsort函数时,只需将cmp函数中的void*类型的指针强制转换为所需类型,即可完成排序。(void*类型的指针是通用型,可以接受任意类型的指针,但是无法进行指针运算,所以在使用时要转换为相应的数据类型)

模拟实现qsort函数

struct stu
{
	char name[10];
	int age;
	double score;
};

void swap(char* buff1, char* buff2,int width)//交换函数
{
	int i = 0;
	for (i = 0; i < width; i++)
	{
		char temp = *buff1;
		*buff1 = *buff2;
		*buff2 = temp;
		buff1++;
		buff2++;
	}
}
int cmp(const void* e1, const void* e2)//比较函数
{
	return ((struct stu*)e1)->age - ((struct stu*)e2)->age;
}
void my_bubble_sort( void* base, int num,int width, int(*cmp)(const void* e1, const void* e2))//注意第四个参数,由于传递上来的是cmp函数的地址,所以需用函数指针来接收
{
	int i = 0;
	int j = 0;
	for (i = 0; i < num-1; i++)//确定排序的趟数
	{
		for (j = 0; j < num - 1-i; j++)//每一趟要比较多少次 
		{


			if (cmp((char*)base + j* width, (char*)base + (j + 1)* width) > 0)//强制转换为char*类型的指针,加多少就代表跳过几个字节
			{
			swap((char*)base + j * width,(char*)base + (j + 1)* width,width);
			 }
		}
	}
}
int main()
{
	struct stu s[3]={{ "zhangsan" ,10, 99.0}, {"lisi",30,89.0} ,{"wangwu",20,100} };//定义结构体数组
	int sz = sizeof(s) / sizeof(s[0]);
	my_bubble_sort(s, sz, sizeof(s[0]), cmp);//用qsort函数的逻辑传递参数
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%s  %d   %.2lf\n", s[i].name,s[i].age,s[i].score);
	}
	return 0;
}

你可能感兴趣的:(c语言)