//此程序的本质:完全理解qsort函数的传参的原则 //
//实现思路:因为我们是模拟qsort函数
//所以我们要自己创造一个:比较数据的函数:cmp_int
//因此必须有一个函数指针来接收这个函数的地址
//所以我们只要书写这个函数,并在后面实现它的比较功能就足以了。
//但是考虑到我们传输的数据类型可能会不同,所以会导致它的大小也不同,所以我们只能使用void接收
//对于我们比较数据的大小,我们比较的是相邻两个数据的大小
// 每次循环过后我们要使数据向后移动一个数据单位,所以我们只能采用数据的宽度来辅助我们实现功能
// 我们将数据类型强制转化为char,然后使用 j * width的形式向后访问一个单位数据的字节大小,一次递增。
//同样的,对于我们实现交换两数据的内容就会造成难度
//因为数据类型的不同,我们也要传过去一个数据类型的地址,这样才算访问一个存储的数据
// 而且交换时我们要一个字节一个字节地交换。
//还是一句话,我们这样做的目的是为了实现这个冒泡排序的普适性
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int cmp_int(const void* e1, const void* e2)
{
return*(int*)e1 - *(int*)e2;//若第一个数据大就返回1,反之就返回0。
//这里的强制类型转化是可以改变的,需要排序什么就运用什么数据类型就可以了
}
void change(char* e1, char* e2, int width)//因为每种数据类型的大小不同,所以要进行一个字节一个字节地交换。
{
while (width--)//通过一个数据的大小来当作判断的标准
{
char* tmp = *e1;
*e1 = *e2;
*e2 = tmp;
e1++, e2++;//总体而言是一个字节一个字节地交换,这是这个程序的精妙的地方
}
}
void my_qsort(void* base, int num, int width,int(*compare)(const void*,const void*))
//这里运用了函数指针因为比较的内容要在新的函数中书写,函数指针是这个程序的精髓。
{
int i = 0;
int j = 0;
for (i = 0; i < num - 1; i++)//这里的两个for循环是冒泡排序的基本格式
{
for (j = 0; j < num - 1 - i; j++)//这个for也是冒泡排序的基本格式
{
if(compare((char*)base + j * width,(char*)base + (j + 1) * width) > 0)//这里是比较两个数据的大小
{
change((char*)base + j * width, (char*)base + (j + 1) * width, width);//这里是成立之后交换两个数字地址中存储的内容
}
}
}
}
int main()
{
int arr[] = { 1,4,5,7,2,22,55,11,44 };//定义一个数组
int sz = sizeof(arr) / sizeof(arr[0]);//计算数组中的元素个数
my_qsort(arr, sz, sizeof(arr[0]), cmp_int);//模拟实现qsort函数
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", *(arr + i));
}//打印数组内容
return 0;
}
程序的结果: