一、qsort()函数简介
qsort()函数是一个用来排序数据的库函数,底层使用的是快速排序的方式。
qsort()函数的特点是其可以排序任何类型的数据。
二、qsort()函数的原型
void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*));
需要应用头文件stdlib.h
三、解读qsort()函数的参数
1. void* base
——无类型指针,指向的是待排序数组的第一个元素,将其转换成 .void*。
2. size_t num
——base指向的待排序数组的元素个数,类型是size_t(无符号整型)。
3. size_t size
——base指向的待排序数组的元素大小,类型是size_t(无符号整型)。
4. int (*compar)(const void*, const void*)
——函数指针,指向的是两个元素的比较函数,有两个void*类型的参数,返回类型是int。
在这个函数内部,可以将传入的两个参数进行比较。如果参数p1>p2,则返回一个大于0的数;如果参数p1==参数p2,则返回0;如果参数p1<p2,则返回一个小于0的数。
书写例子如下:
int compareMyType (const void * p1, const void * p2) { if ( *(MyType*)p1 < *(MyType*)p2 ) return -1; if ( *(MyType*)p1 == *(MyType*)p2 ) return 0; if ( *(MyType*)p1 > *(MyType*)p2 ) return 1; }
当返回值大于0时,交换两个元素的值;如果返回值小于等于0,则不进行交换。
代码运行后,可以得到一组升序排列的数组。如果想获得降序数组,将*p1 - *p2换成*p2 - *p1即可。
参数的类型为void*(无类型指针),这样设计的原因是因为不清楚要比较的元素是什么类型,而void*类型的指针可以接收任意类型的指针,这样就避免了因类型不符而产生的错误。
因为void*类型不能进行解引用和+ -整数的操作,所以在进行运算时,要强制类型转换。
compar()函数用例:
1.对一维数组排序
int compare (const void * p1, const void * p2) { return *(int*)p1 - *(int*)p2; }
2.对二维数组排序
int compare (const void * p1, const void * p2) { //按元素第一列元素大小排序 return ((int*)p1)[0] - ((int*)p2)[0]; }
3.对结构体排序
struct Stu { char name[20]; int age; } //对字符串排序 int compare (const void * p1, const void * p2) { return strcmp(((struct Stu*)p1)->name,((struct Stu*)p2)->name); } //对整型排序 int compare (const void * p1, const void * p2) { return ((struct Stu*)p1)->age - ((struct Stu*)p2)->age; }
四、完整代码
对一维数组排序
int cmp_int(const void* p1, const void* p2) { return *(int*)p1 - *(int*)p2;//升序 } int main() { int arr[] = { 2,5,4,6,3,1,7,8,9,0 }; int sz = sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_int); for (int i = 0; i < sz; i++) printf("%d ", arr[i]); return 0; }
结构体
(1)按照名字排序
struct Stu { char name[20]; int age; } int cmp_int(const void* p1, const void* p2) { return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);//升序 } int main() { struct Student stu[3] = { {"zhangsan",19},{"lisi",30},{"wangwu",25} }; int sz = sizeof(stu) / sizeof(stu[0]); qsort(stu, sz, sizeof(stu[0]), cmp_char); for (int i = 0; i < sz; i++) printf("%s %d", stu[i].name, stu[i].age); return 0; }
(2)按照年龄排序
struct Stu { char name[20]; int age; } int cmp_int(const void* p1, const void* p2) { return ((struct Stu*)p1)->age - ((struct Stu*)p2)->age;//升序 } int main() { struct Student stu[3] = { {"zhangsan",19},{"lisi",30},{"wangwu",25} }; int sz = sizeof(stu) / sizeof(stu[0]); qsort(stu, sz, sizeof(stu[0]), cmp_int); for (int i = 0; i < sz; i++) printf("%s %d", stu[i].name, stu[i].age); return 0; }