qsort库函数作用:执行快速排序
其需要引用的头文件是 : <stdlib.h>
qsort 默认(按照 e1,e2 顺序)排的是升序
其中每个参数解释是:
关于比较两个元素的函数 :
如果e1小于e2,则返回小于0的数
如果e1等于e2, 则返回等于0的数
如果e1大于e2, 则返回大于0的数
实列举列1:使用qsort库函数实现对数字的升序排序
#include <stdio.h>
#include <stdlib.h>
void print_arr(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2; // (int*) 因为无法对 void* 直接解引用,因此将其强制类型转换为int*,再解引用
}
int main()
{
int arr[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_int);
print_arr(arr, sz);
}
而如果要排降序,只需要将 *(int*)e1 - *(int*)e2 改为 *(int*)e2 - *(int*)e1
其他不变 ;
实列讲解2:qsort实现对结构体进行快速排序
struct Stu
{
char name[20];
int age;
};
int cmp_by_name(const void* e1, const void* e2)
{
return strcmp(((struct Stu*)e1)->name , ((struct Stu*)e2)->name);
}
void text2()
{
struct Stu s[3] = { { "张三", 15 }, { "李四", 30 }, { "王五", 10 } };
int sz = sizeof(s) / sizeof(s[0]);
// 按照名字进行排序
qsort(s, sz, sizeof(s[0]), cmp_by_name);
}
int main()
{
text2();
}
排序成功
按照年龄来排:
struct Stu
{
char name[20];
int age;
};
int cmp_by_age(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
void text2()
{
struct Stu s[3] = { { "张三", 15 }, { "李四", 30 }, { "王五", 10 } };
int sz = sizeof(s) / sizeof(s[0]);
// 按照年龄进行排序
qsort(s, sz, sizeof(s[0]), cmp_by_age);
}
int main()
{
text2();
}
排序成功:王五-10 张三 -15 李四 - 30
下面我们来模拟qsort函数: 使用回调函数实现一个通用的冒泡排序函数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void print_arr(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2; // 排升序 (若要排降序,则e2-e1)
}
// 使用回调函数实现一个通用的冒泡排序函数
void Swap(char* buf1, char* buf2, int width)
{
int i = 0;
for (i = 0; i < width; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
void BubbleSort(void* base, size_t num, size_t width, int(*cmp)(const void* e1, const void* e2))
{
size_t i = 0;
for (i = 0; i < num - 1; i++)
{
size_t j = 0;
for (j = 0; j < num - 1 - i; j++)
{
// 排升序 -- 第一个比第二个大 交换
if (cmp((char*)base+j*width,(char*)base+(j+1)*width)>0)
{
Swap((char*)base + j * width, (char*)base + (j + 1) * width,width);
}
}
}
}
// 测试自定义的BubbleSore();
void test3()
{
int arr[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
int sz = sizeof(arr) / sizeof(arr[0]);
BubbleSort(arr, sz, sizeof(arr[0]), cmp_int);
print_arr(arr, sz);
}
int main()
{
// 测试自定义的BubbleSore();
test3();
return 0;
}
可见,升序排序成功;
下面再测试 ,实现对结构体的排序(按照年龄)
void Swap(char* buf1, char* buf2, int width)
{
int i = 0;
for (i = 0; i < width; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
void BubbleSort(void* base, size_t num, size_t width, int(*cmp)(const void*, const void*))
{
size_t i = 0;
//趟数
for (i = 0; i < num - 1; i++)
{
//比较的对数
size_t j = 0;
for (j = 0; j < num - 1 - i; j++)
{
//base[j] ==> *(base+j)
if (cmp((char*)base + j*width, (char*)base + (j + 1)*width)>0)
{
//交换
Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
}
}
}
}
struct Stu
{
char name[20];
int age;
};
int cmp_by_age(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
void text4()
{
struct Stu s[3] = { { "张三", 15 }, { "李四", 30 }, { "王五", 10 } };
int sz = sizeof(s) / sizeof(s[0]);
// 按照年龄进行排序
BubbleSort(s, sz, sizeof(s[0]), cmp_by_age);
}
int main()
{
text4();
}
排序后:
变成 王五 10 张三 15 李四 30 ,排序成功,测试成功。
说明BubbleSort 函数模拟的qsort函数成功 ~~