两者同样都是排序的方法那qsort库函数的优势到底在哪儿;
首先我们得先了解一下冒泡排序
1.只能排列有序数组
2.时间复杂度较高 不稳定;
冒泡排序的思想就是一个数组中的元素两两进行比较
如上图这般需要进行8次两两交换才能确定一个数字的位置
所以总共要进行八次这样的循环才能确定每个数的位置排成升序效率很低;
下面介绍一种高效率的库函数qsort,需要引用头文件<stdlib.h>
qsort的优点相对明显
它可以直接拿来使用,并且可以排序任何类型的数据
void qsort (
void* base, //要排序的目标数组
size_t num, //待排序的元素个数
size_t width, //一个元素的大小,单位是字节
int(*cmp)(const void* e1, const void* e2)
);
qsort有四个参数,前三个如上注释所示
最后一个参数是函数指针
int(*cmp)(const void* e1,const void* e2)
这个指针指向一个函数,这个函数需要比较两个元素的大小,所以需要我们自己来敲这个函数
那么就不得不讨论一下为什么这个函数为什么得我们自己来写;
前面说过qsort可以排序任何类型的数据,
如果我们要比较两个数的大小,使用>和<即可;
如果我们要比较字符串的大小,就要用到strcmp;
如果我们要比较结构体数据的大小, 以上两种方法都不可行,所以我们要指定一个标准来判断两个元素的大小 ,只要将这两个元素怎么比的大小告诉qsort函数,那么qsoer就可以帮你排出顺序;
这里我们继续拿整型数组来举例;
test()
{
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);//qsort是默认排成降序的
print_arr(arr, sz);
}
int main()
{
test();
return 0;
}
qsort中的参数依次为要排序的目标数组,待排序的元素个数,其中一个元素的大小(单位是字节),两个数据比大小的函数;
int(*cmp)(const void* e1,const void* e2)
cmp函数中的参数是两个待比较元素的地址,比如说我们将9和8进行比较,那么就将9的地址传给第一个参数,也就是e1;将8的地址传给第二个参数,也就是e2;使用void*类型的指针也是因为qosrt可以任意类型的数据,所以要比较的两个元素就不能确定,得使用void*类型的指针 ,如下
int cmp_int(const void* p1, const void* p2)
{
}
接下来就需要利用指针找到两个整形来比大小,那么直接用*p1和*p2来比较可以吗?
显然不行
因为函数的参数是const void型指针,void*类型指针是无类型指针,也可以认为是通用类型的指针,他可以接受任何类型的地址
所以我们对指针解应用时,要对其类型进行强制转换,
最后写为*(int*)p1,这样才可以对指针中的值进行应用
最后再将两个数值比大小,那不妨将两个数做差;如下
int cmp_int(const void* p1, const void* p2)
{
return *(int*)p1 - *(int*)p2;
}
这样函数返回值可以是>0,=0或<0,这样qsort函数中的参数便完整了,接下来将其内容打印出来即可,完全代码如下
int cmp_int(const void* p1, const void* p2)
{
return *(int*)p1 - *(int*)p2;//按照降序排列;
//return *(int*)p2 - *(int*)p1;//按照升序排列;
}
void print_arr(int arr[],int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
test()
{
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);//qsort是默认排成降序的
print_arr(arr, sz);
}
int main()
{
test();
return 0;
}
相信你一定有所收获