qsort函数:可以实现不同类型数据的排序:
函数使用:
整形数组排序:
输入数组:a[6]={ 3,5,96,8,99,2 };
排序后的数组:a[6]={ 2,3,5,8,96,98 };
结构体数组
数组结构体数组:struct human s[3] = { {"zbc",20},{"pcd",30},{"ade",50} };
排序后的数组结构体数组:struct human s[3] = { {"ade",50},{"pcd",30},{"abc",20} };
current_bubble_sort()函数------基于冒泡排序的思想设计实现库函数qsort的相关功能
1.因为预先不知道要排序的数据类型,所以用四个参数来确定相关信息:
1.1待排序数组的首地址 base,因为不知道数组元素的类型,所以定义为void* base;
1.2数组元素个数 num,定义为int num;
1.3数组元素长度 width,定义为 int width;
1.4判断函数function函数,定义为 int (*function) (const void* e1,const void* e2);
2.搭建冒泡函数框架:
2.1对于num个元素,需要排序num-1个数据,所以外层确定循环次数时
2.2每一次排序时,要操作的数据个数也是不同的,为num-1-i
void current_bubble_sort(void* base, int num, int width, int (*function)(const void* e1, const void* e2))
{
for (int i = 0; i < num - 1; i++)
{
for (int j = 0; j < num - 1 - i; j++)
{
?
}
}
}
3.判断是否需要交换元素的顺序:
3.1使用function函数比较两个数的大小,function函数返回值是1,说明第一个元素大于第二个元素,返回值是0时,说明两个元素相等,返回值是-1,说明第一个元素小于第二个元素。
3.2如果默认是升序排序,那么返回值是1时,进行排序。
3.3function函数的参数分别是两个待比较元素的地址,因为只涉及到函数的比较,不涉及函数数据的改变,为了安全起见,用const函数修饰地址。
3.4function的函数参数是要比较两个数组元素,用base(数组首元素地址)+步长*j。
3.5将function函数的地址指针强制转化为char* 类型,步长为1。
3.6实现结果: if (function((char*)base+j*width, (char*)base+(j+1)*width) > 0)
4.交换函数swap函数
4.1核心就是交换两个待交换数据的单个字节。
4.2参数是要交换元素的地址和元素类型的宽度
4.3最终代码为:void swap(char* swap1, char* swap2, int swapwidth)
5.打印函数
5.1整型数组打印没什么好说的
5.2结构体数组打印内容时,注意正确的打印格式,指针->结构体变量名;
#include
#include
//用冒泡排序的思想模仿qsort函数实现一个通用的排序算法
struct human
{
char name[20];
int age;
};
void swap(char* swap1, char* swap2, int swapwidth) // 单个字节传输
{
for (int i = 0; i < swapwidth; i++)
{
char temp = *swap1;
*swap1 = *swap2;
*swap2 = temp;
swap1++;
swap2++;
}
}
int function_int(const void* e1, const void* e2)
{
return (*(int*)e1) - (*(int*)e2);
}
int function_struct(const void* e1, const void* e2)
{
return strcmp(((struct human*)e1)->name, ((struct human*)e2)->name);
}
void current_bubble_sort(void* base, int num, int width, int (*function)(const void* e1, const void* e2))
{
for (int i = 0; i < num - 1; i++)
{
for (int j = 0; j < num - 1 - i; j++)
{
if (function((char*)base+j*width, (char*)base+(j+1)*width) > 0)
{
//大于零、升序交换
//实现方法不知道,需要函数使用者编写
swap((char*)base + j * width, (char*)base + (j + 1) * width, width);//直接交换字节
}
}
}
}
void print1(int a[], int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%d ", a[i]);
}
}
void print2(struct human s[], int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%s %d\n", (*(s + i)).name, (s + i)->age);
}
}
int main()
{
int a[6] = { 3,5,96,8,99,2 };
int sz1 = sizeof(a) / sizeof(a[0]);
struct human s[3] = { {"zbc",20},{"pcd",30},{"ade",50} };
int sz2 = sizeof(s) / sizeof(s[0]);
current_bubble_sort(a, sz1, sizeof(a[0]), function_int);
current_bubble_sort(s, sz2, sizeof(s[0]), function_struct);
printf("数组排序后的结果:->\n");
print1(a, sz1);
printf("\n");
printf("结构体按照首元素字符排序后的结果:->\n");
print2(s, sz2);
return 0;
}
特别鸣谢:哔哩哔哩比特鹏哥的视频教学课。