八大排序中,冒泡排序最容易实现,所以这里用冒泡排序来模拟实现快排,但是想要实现库函数中快排的功能并不容易,因为不仅要实现数字排序,还要实现各种各样类型的排序,这样引发的问题就是各种类型的大小不同,无法用固定的类型接收数据。
四个参数
第一个:要排序的空间的首元素地址;
第二个:要排序的个数;
第三个:一个类型的大小;
第四个:函数地址(自己写个比较函数,传入函数地址(函数名))。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct student //排序结构体
{
char arr[15];
int age;
}stu;
int cmp_stu_name(const void* e1, const void* e2) //以结构体中姓名成员排序
{
return strcmp(((stu*)e1)->arr, ((stu*)e2)->arr); //使用字符串比较函数
}
int cmp_stu_age(const void* e1, const void* e2) //以结构体中年龄成员排序
{
return ((stu*)e1)->age - ((stu*)e2)->age;
}
int cmp_int(const void* e1, const void* e2) //以整型数字排序
{
return *(int*)e1 - *(int*)e2;
}
void my_swap(char* buf1, char* buf2, int width) //交换函数
{
for (int i = 0; i < width; i++)
{
char tmp = *(buf1 + i);
*(buf1 + i) = *(buf2 + i);
*(buf2 + i) = tmp;
}
}
void my_sort(void* base, int sz, int 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) > 0)
{
my_swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
}
}
}
}
int main()
{
int arr1[10] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; //测试数字排序
int sz1 = sizeof(arr1) / sizeof(arr1[0]);
int width1 = sizeof(arr1[0]);
stu arr2[3] = { {"zhangsan", 10}, {"lisi", 50}, {"wangwu", 30} }; //测试结构体排序
int sz2 = sizeof(arr2) / sizeof(arr2[0]);
int width2 = sizeof(arr2[0]);
my_sort(arr2, sz2, width2, cmp_stu_name);
my_sort(arr2, sz2, width2, cmp_stu_age);
my_sort(arr1, sz1, width1, cmp_int);
for (int i = 0; i < sz1; i++)
{
printf("%d ", arr1[i]);
}
system("pause");
return 0;
}