c语言:qsort()函数
先来看一下qsort函数的原型
void qsort( void *base,
size_t num,
size_t width,
int (__cdecl *compare )(const void *elem1, const void *elem2 ) );
qsort()函数需要的头文件#include <stdlib.h>
是的这函数看起来复杂,如果你一步步来看的话其实就那么回事。
base:待排序的数组
num:数组元素的个数
width:每个元素的大小
compare:这是一个函数指针,指向的是一个来比较相邻两个元素的大小的函数,但这个函数要自己写!
int (__cdecl *compare )(const void *elem1, const void *elem2 ) )
自己实现比较函数,一般是拿两个参数相减返回差值
compare的返回值 | 实现 |
---|---|
>0 | elem1被排在elem2后面 |
<0 | elem1被排在elem2前面 |
=0 | 位置不发生变化 |
qsort这个函数到底怎么用呢,我这会举例各种类型的比较函数和各种类型传参
1.整形
2.浮点型
3.字符
4.结构体
先来看整形,
#include <stdio.h>
#include <stdlib.h>
int cmp_int(const void* s1, const void* s2)
{//比较整形
return *(int*)s1 - *(int*)s2;
}
//打印整形数组
void print(int* arr, int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = { 9,2,1,3,4,10,5,6,8,7 };
qsort(arr,
sizeof(arr) / sizeof(arr[0]),
sizeof(arr[0]),
cmp_int);
print(arr, sizeof(arr) / sizeof(arr[0]));
return 0;
}
字符型
比较字符型这里我用的是strcmp函数,需要#include<string.h>头文件。
简单说一下strcmp函数是用来比较字符串大小的,从左到右依次比较字符串每个字符的ASCII码值大小,我们这用来比较字符也是每问题的。
恰巧的是strcmp函数的返回值和比较函数是一样的,
s1>s2返回大于0的数
s1<s2返回小于0的数
s1==s2返回0
也可以看看->strcmp函数介绍
#include <stdio.h>
#include <stdlib.h>
int cmp_char(const void* s1, const void* s2)
{//比较字符型
return strcmp((char*)s1, (char*)s2);
}
//打印字符数组
void print2(char* arr, int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%c ", arr[i]);
}
printf("\n");
}
int main()
{
char arr2[] = { 'b','c','d','e','a','f','\0' };
qsort(arr2,
sizeof(arr2) / sizeof(arr2[0]),
sizeof(arr2[0]),
cmp_char);
print2(arr2, sizeof(arr2) / sizeof(arr2[0]));
return 0;
}
浮点型
#include <stdio.h>
#include <stdlib.h>
int cmp_float(const void* s1, const void* s2)
{//比较浮点型
return *(float*)s1 - *(float*)s2;
}
void print3(float* arr, int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%.1f ", arr[i]);
}
printf("\n");
int main()
{
float arr3[] = { 2.2,1.1,4.4,3.3,9.9,8.8,5.5,6.6,7.7 };
qsort(arr3,
sizeof(arr3) / sizeof(arr3[0]),
sizeof(arr3[0]),
cmp_float);
print3(arr3, sizeof(arr3) / sizeof(arr3[0]));
return 0;
}
结构体数组
我简单声明了一个结构,内容是书名和价格
比较函数那里,因为解引用的的优先级要高于强制转换,所以用括号括起来.
我写了两个比较函数,让结构体按分别按名字排序和价格排序。
#include <stdio.h>
#include <stdlib.h>
struct book
{
char name[20];
int price;
};
int cmp_struct_name(const void* s1, const void* s2)
{//比较结构体,按名字排序
return strcmp(((struct book*)s1)->name, ((struct book*)s2)->name);
}
int cmp_struct_price(const void* s1, const void* s2)
{//比较结构体,按价格排序
return ((struct book*)s1)->price - ((struct book*)s2)->price;
}
//打印结构体数组
void print4(struct book* s1, int sz)
{
int i = 0;
for (i = 0; i < 3; i++)
{
printf("%s ", s1->name);
s1++;
}
printf("\n");
}
int main()
{
struct book bk[] = { {"c plus",35},{"java",30},{"html+css",25} };
//按名字排序
qsort(bk,
sizeof(bk) / sizeof(bk[0]),
sizeof(bk[0]),
cmp_struct_name);
print4(bk, sizeof(bk) / sizeof(bk[0]));
//按价格排序
qsort(bk,
sizeof(bk) / sizeof(bk[0]),
sizeof(bk[0]),
cmp_struct_price);
print4(bk, sizeof(bk) / sizeof(bk[0]));
return 0;
}
所有代码的实现效果
当然这里是按升序排列的,如果想按降序排列的话其实很简单,只需要把比较函数返回值那里的两个参数换个位置就可以了。
列如整形想从升序变成降序的话,把s1和s2换个位置就行了
int cmp_int(const void* s1, const void* s2)
{//整形升序
return *(int*)s1 - *(int*)s2;
}
int cmp_int(const void* s1, const void* s2)
{//整形降序
return *(int*)s2 - *(int*)s1;
}
如过想了解该函数时怎么实现的,可以看看该函数的模拟实现qsort的模拟实现