函数定义
基于快速排列的一个函数,它的四个参数的含义:
1、void* base,是排序开始的地址
2、size_t num 想要排列的个数
3、size_t size 排列对象,一个占多少空间(字节)
4、int (*comper)(void*,void*) 我们自己写的对比函数,用于确定元素排列的顺序,是逆序还是正序
(其返回值决定,是否交换这两个数,返回值 >0 时 交换)
其用法一般如下:(以int 型示例)
// 升序排列(当前者>后者,返回正数 1 表示交换)
int comper(void* a, void* b){if (*(int*)a > *(int*)b)return 1;else if (*(int*)a < *(int*)b)return -1;elsereturn 0;//简化为
// return *(int*)a-*(int*)b;}
为什么都是void 型呢?因为void具有广泛性,所有的类型都能使用这个函数
下面示例实现,int类型的升序排列
#include<stdlib.h>
// 根据需求,自定义比较函数,
// 比较类型int 升序
int comper_int(void* a, void* b)
{//根据想要的类型,强制转换return *(int*)a - *(int*)b;
//想要降序,只需要颠倒a与b的位置
}int main()
{int arr[] = { 3,9,1,6,3,10,2,0,4,8 };// 求元素个数int num = sizeof(arr) / sizeof(arr[0]);// 求一个元素所占字节大小int size = sizeof(arr[0]);qsort(arr,num , size, comper_int);int i = 0;for (i = 0; i < num; i++){printf("%d ", arr[i]);}// 0 1 2 3 3 4 6 8 9 10return 0;
}
其他类型也可以,比如 浮点型:
#include<stdlib.h>
//float型,降序
int comper_f(void* em1, void* em2)
{return *(float*)em2 - *(float*)em1;
}int main()
{float brr[] = { 4.5,10.666,1.1, 3.09,2.959 };// 求元素个数int num = sizeof(brr) / sizeof(brr[0]);// 求一个元素所占字节大小int size = sizeof(brr[0]);qsort(brr, num, size, comper_f);int i = 0;for (i = 0; i < num; i++){printf("%.3f ", brr[i]);}// 10.666 4.500 3.090 2.959 1.100return 0;
}
模拟实现 qsort 函数的功能:
// 不确定函数类型,一个字节一个字节的交换
void Swap_(char* a, char* b, int n)
{while (n--){char c = *a;*a = *b;*b = c;a++;b++;}
}void my_qsort(void* base, size_t num, size_t size, int(*comper)(void*, void*))
{int i = 0;// 比较多少趟for (i = 0; i < (int)num-1; i++){int j = 0;// 每趟左右俩数比较多少次for (j = 0; j < (int)num - 1 - i; j++){//不确定元素类型,就用元素所占字节来确定位置// 去一趟确定一个末尾的数,少一个要比较的数if (comper((char*)base + j * size, (char*)base + (j + 1) * size) > 0){//满足条件 交换位置Swap_((char*)base + j * size, (char*)base + (j + 1) * size, size);}}}
}int comper_int(void* a, void* b)
{return *(int*)a - *(int*)b;
}int main()
{int arr[] = { 3,9,1,6,3,10,2,0,4,8 };int num = sizeof(arr) / sizeof(arr[0]);int size = sizeof(arr[0]);my_qsort(arr, num, size, comper_int);int i = 0;for (i = 0; i < num; i++){printf("%d ", arr[i]);}return 0;
}
在my_qsort 函数中为什么使用(char*)呢?
因为:
面对不同要比较的类型,所占字节不一定,
而char 所占一个字节就是最小单位,
它的访问权限也就是一个字节大小,
在最小单位的基础上,根据加减 类型的size(字节数)来准确确定位置;
Swap函数也是同理,一个字节是最小单位,
每个字节所对应的值都交换了,俩数也就交换了。