在我们不了解qsort之前,冒泡排序可能是我们最常用的一种排序方法,但是冒泡排序法可用的范围太小了,比如需要排序结构体中的成员时自己动手拓展也会很麻烦。
这时候我们可以了解一下qsort排序函数,让我们变的更高级一点哈哈哈。
我们可以从库函数网站www.cplusplus.com中认识到这个qsort,首先运用这个函数之前我们要使用相应的头文件#include
接着我们来了解一下qsort的组成:
qsort函数中用到了四个参数,我们首先来了解一下这四个参数的意思
2、size_t num:待排序数组的元素个数。
3、size_t size:待排序数组中一个元素的大小。
4、int (*compar)(const void*,const void*):函数指针—compar指向了一个函数,这个函数是用来比较两个元素的大小。
这里可能会有朋友们感到疑惑,为什么1、4参数类型要用void*类型的指针,我们先来解答一下这个:
void*:1、void*类型的指针—不能进行解引用操作符,也不能进行+-整数的操作,因为我们并不知道他是什么类型。
2、void*类型的指针是用来存放任意类型数据的地址(形象点来说就是垃圾桶)。
我们之所以在这里用void*类型的指针,就是qsort函数并不知道你要排序的是什么类型的,所以可以用void*类型的指针来存放我们想要排序类型数据的地址,这样看来,qsort函数的范围确实是大于普通冒泡排序的范围的。
int arr[10] = { 10,9,8,7,6,5,4,3,2,1 };
int sz = sizeof(arr) / sizeof(arr[0]);
print_arr(arr, sz);
qsort(arr, sz, sizeof(arr[0]), ???);
我们定义好一个数组之后,根据以上对qsort函数参数的解释,我们可以写出对相应的实参,前三个实参对于我们来说是很简单的,但是对于int (*compar)(const void*,const void*) 这个比较函数我们会有点摸不着头脑:这个是要自己写的?
当然,这个并不是qsort函数自带的,不是自带的又如何,写出一个比较函数还不是简简单单吗。
我们先拿int型数组举例:
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
此时我们需要比较的是int型的元素,所以我们将e1、e2强制转化为int*类型的指针,再解引用得到元素相减即可比较出大小。如下:
int arr[10] = { 10,9,8,7,6,5,4,3,2,1 };
int sz = sizeof(arr) / sizeof(arr[0]);
print_arr(arr, sz);
qsort(arr, sz, sizeof(arr[0]), cmp_int);
结果:
如果只有int型的排序那还是太逊啦。
假如我们想排序结构体中的元素呢?这时候我们可以再写一个比较函数,来进行结构体成员的比较
定义结构体:
struct stu
{
char name[30];
int age;
};
初始化结构体:
struct stu arr[] = { {"zhangsan",20},{"lisi",18},{"wangwu",22} };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]),???);
结构体成员有名字和年龄两个,这两个我们都可以比较吗,答案是肯定的。只要比较函数写的好,什么都可以比较。
比较年龄:
int cmp_struct_stu(const void* e1, const void* e2)
{
return ((struct stu*)e1)->age - ((struct stu*)e2)->age;
}
这个大致与int型数组元素的比较差不多,需要注意的是怎么指向结构体中的成员。
结果:
比较名字:这里我们按名字首字母先后顺序比较。
int comp_by_stu_name(const void* e1, const void* e2)
{
return (strcmp(((struct stu*)e1)->name, ((struct stu*)e2)->name));
}
这里需要注意的是,我们在比较字符串的时候,需要用的是strcmp函数来比较,并且要用到其对应的头文件#include
结果:
读完的小伙伴可能会发现,为什么都是升序呢?如果我想降序呢?
我们拿int型数组举例:
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e2 - *(int*)e1;
}
重新定义arr数组:
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
print_arr(arr, sz);
qsort(arr, sz, sizeof(arr[0]), cmp_int);
print_arr(arr, sz);
return 0;
打印结果:
综上,qsort对我们的帮助要更为大一些,因为它适用的范围更大,用起来也更为方便。
认识qsort函数还不够,我会带你去深入了解qsort
下次我们来讲怎样用冒泡排序来实现我们的qsort函数,了解qsort函数是怎样实现排序的