119.【C语言】数据结构之快速排序(调用库函数)
目录
1.C语言快速排序的库函数
1.使用qsort函数前先包含头文件
2.qsort的四个参数
3.qsort函数使用
对int类型的数据排序
运行结果
对char类型的数据排序
运行结果
对浮点型数据排序
运行结果
2.题外话:函数名的本质
1.C语言快速排序的库函数
cplusplus网的介绍 https://legacy.cplusplus.com/reference/cstdlib/qsort/?kw=qsort
解释:
1.使用qsort函数前先包含头文件<stdlib.h>
2.qsort的四个参数
base:指向要排序的数组(即数组名)
num:数组元素的个数(类型size_t)
size:每个元素所占的空间(类型size_t)
compare:比较函数,用于比较数组的两个元素(这个参数有点特殊,之前没有见过:函数本身也可以作为另一个函数的参数)
函数没有返回值(void类型)
网站给出比较函数应该遵照的原型:int compar (const void* p1, const void* p2);
注意到比较函数的返回类型为int(显然有三种情况,负数,0和正数)
负数 0 正数 *p1<*p2 *p1==*p2 *p1>*p2
网站给出比较函数的写法
int compareMyType (const void * a, const void * b) { if ( *(MyType*)a < *(MyType*)b ) return -1; if ( *(MyType*)a == *(MyType*)b ) return 0; if ( *(MyType*)a > *(MyType*)b ) return 1; }
由于a是void*类型的,使用前应该强制类型转换为MyType类型,之后再解引用
3.qsort函数使用
对int类型的数据排序
#include <stdlib.h>
int compare(const void* a, const void* b)
{
if (*(int*)a < *(int*)b) return -1;
if (*(int*)a == *(int*)b) return 0;
if (*(int*)a > *(int*)b) return 1;
}
int main()
{
int arr[] = { 3,5,1,6,2,3,9,0,8 };
printf("排序前:");
PrintArray(arr, sizeof(arr) / sizeof(arr[0]));
qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), compare);
printf("排序后:");
PrintArray(arr, sizeof(arr) / sizeof(arr[0]));
return 0;
}
备注:如果要排降序,compare函数有两种改法①将compare的返回值-1和1交换即可 ②或者将>和<交换
运行结果
对char类型的数据排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare(const void* a, const void* b)
{
if (*(char*)a < *(char*)b) return -1;
if (*(char*)a == *(char*)b) return 0;
if (*(char*)a > *(char*)b) return 1;
}
int main()
{
char arr[] = { "aoxhfekmc"};
printf("排序前:");
printf("%s", arr);
qsort(arr, sizeof(arr) / sizeof(arr[0])-1, sizeof(char), compare);
printf("\n排序后:");
printf("%s", arr);
return 0;
}
运行结果
对浮点型数据排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare(const void* a, const void* b)
{
if (*(float*)a < *(float*)b) return -1;
if (*(float*)a == *(float*)b) return 0;
if (*(float*)a > *(float*)b) return 1;
}
int main()
{
float arr[] = { 3.1,5.4,7.9,10.31,6.66,1.1,0.9 };
printf("排序前:");
for (int i = 0;i < sizeof(arr) / sizeof(arr[0]); i++)
printf("%.2f ", arr[i]);
qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(float), compare);
printf("\n排序后:");
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
printf("%.2f ", arr[i]);
return 0;
}
运行结果
2.题外话:函数名的本质
在解释qsort函数的时候提到了"函数本身也可以作为另一个函数的参数"
测试以下代码,下断点至return 0;然后执行到断点处
#include <stdio.h>
#include <stdlib.h>
int compare(const void* a, const void* b)
{
if (*(float*)a < *(float*)b) return -1;
if (*(float*)a == *(float*)b) return 0;
if (*(float*)a > *(float*)b) return 1;
}
int main()
{
printf("%p", compare);
return 0;
}
查看打印结果
在内存窗口中输入0x00C613FC后发现内存窗口直接跳到了0x00C61900;转到反汇编,查看compare函数的第一个指令的机器码和地址
因此函数名的本质是地址,其指向函数反汇编的第一条指令