前言
包含<stdlib.h>头文件即可使用库函数qsort用于排序。
参数base:用于排序的首元素地址(可以这样理解,相当于传入一个数组的首地址用于后续比较,个人理解不一定严谨)。
参数num:传入排序元素的个数。
参数size:排序元素的字节大小。
参数compar:函数指针,用于比较不同类型的数据。
qsort函数内部使用快排的思想实现,下面将给出模仿qsort函数参数的通用的冒泡排序。
1、排序函数
void my_bubble_sort(void* base,int count,int size,int(*cmp)(const void* v1,const void* v2))
{
int i = 0;
int j = 0;
for (i = 0; i < count - 1; i++)
{
for (j = 0; j < count - 1 - i; j++)
{
if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
{
swap((char*)base + j * size, (char*)base + (j + 1) * size,size);
}
}
}
}
代码的循环条件和普通排序整形的冒泡排序是一致的,只有比较和交换不同。
cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0
为了使传入地址适用于任何类型,选择char*数据类型并且根据数据类型的字节大小计算出元素的地址传入比较函数。
swap((char*)base + j * size, (char*)base + (j + 1) * size,size)
交换函数的思想与上面也一致。
2、比较函数
typedef struct student
{
char name[20];
int age;
}stu;
int cmp_stu_name(const void* v1,const void* v2)
{
return strcmp(((struct student*)v1)->name, ((struct student*)v2)->name);
}
函数使用void* 类型来接收地址,void* 相当于垃圾桶,可以接受任何类型的地址,之后再强转为其它需要类型的指针进行比较。你需要比较什么类型的数据,就写强转为什么类型的指针访问数据进行比较。以上代码给出的是用于比较已有结构体类型中姓名字符串的函数。
3、交换函数
void swap(void* p1,void* p2,int size)
{
int i = 0;
for (i=0;i<size;i++)
{
char tmp = *((char*)p1 + i);
*((char*)p1 + i) = *((char*)p2 + i);
*((char*)p2 + i) = tmp;
}
}
函数通过交换每个字节的数据达到交换效果。