q
s
o
r
t
(
)
qsort()
qsort() 函数是C语言 srdlib.h
库中的排序函数。此函数使用快速排序算法,时间复杂度一般在
O
(
l
g
(
n
)
)
O(lg(n))
O(lg(n)) 。因此是一种强大的排序方法。本文即介绍
q
s
o
r
t
(
)
qsort()
qsort() 函数及其使用方法。
qsort()的参数
q s o r t ( ) qsort() qsort() 函数中共包含四个参数。此函数的声明为:
qsort(void * Base, size_t _NumOfElements, size_t _SizeOfElements, _CoreCrtNonSecureSearchSortCompareFunction _CompareFunction)
。
接下来我们分别解释这四个参数。
void * Base
:第一个参数,要求传入的参数是一个指针。这个指针应当指向待排序数组。
size_t _NumOfElements
:第二个参数,传入待排序的元素个数。
size_t _SizeOfElements
:第三个参数,传入待排序元素类型的大小。一般而言,我们可以使用 sizeof(num[0])
来获取元素的大小。( num
是待排序的数组)
_CoreCrtNonSecureSearchSortCompareFunction _CompareFunction
:第四个参数,要求传入一个函数指针,这个函数的作用是比较两个元素大小。
专门解释一下第四个参数。这个函数接受两个元素,我们需要确定这两个元素之间的大小(通过返回值的正负确定)。qsort()
函数提供了排序的算法,我们需要做的就是提供元素间的比较方法。
qsort()的使用
最简单的,先从对两个整型排序说起:
#include <stdio.h>
#include <stdlib.h>
int num[100];
int n;
int cmp(const void* a, const void* b){
int* pa = (int*)a;
int* pb = (int*)b;
return *pa - *pb;
}
int main(){
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%d", &num[i]);
qsort(num, n, sizeof(num[0]), cmp);
for(int i = 0; i < n; i++)
printf("%d ", num[i]);
return 0;
}
对于 cmp()
这个比较函数,返回值和形式参数的声明是固定的。在比较的时候,我们需要首先将 const void*
类型的指针强制类型转换为我们需要的类型指针,之后再进行比较。返回值正负决定了 qsort()
的排序行为。
再举一个对二维数组排序的例子(对第一关键字进行升序排序,第一关键字相同时对第二关键字进行降序排序)。
#include <stdio.h>
#include <stdlib.h>
int num[100][2];
int n;
int cmp(const void* a, const void* b){
int* pa = (int*)a;
int* pb = (int*)b;
if(pa[0] != pb[0])
return pa[0] - pb[0];//对第一关键字排序
else
return -(pa[1] - pb[1]);//对第二关键字排序
}
int main(){
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%d%d", &num[i][0], &num[i][1]);
qsort(num, n, sizeof(num[0]), cmp);
for(int i = 0; i < n; i++)
printf("%d %d\n", num[i][0], num[i][1]);
return 0;
}
除此之外,我们也可以对自定义的结构体进行排序(对
i
d
id
id 进行升序排序,
i
d
id
id 相同则对
v
a
l
u
e
value
value 进行升序排序):
对 double
类型的排序不能直接进行相减,而要用到三目运算符。在对大数字进行排序时,如果在对两个数字进行相减运算时可能会发生溢出,则也应该使用三目运算符的写法。
#include <stdio.h>
#include <stdlib.h>
typedef struct Stu Stu;
struct Stu{
int id;
double value;
};
Stu num[100];
int n;
int cmp(const void* a, const void* b){
Stu* pa = (Stu*)a;
Stu* pb = (Stu*)b;
if(pa->id != pb->id)
return pa->id - pb->id;
else
return pa->value - pb->value > 0 ? 1 : -1;//使用三目运算符传返回值。
}
int main(){
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%d%lf", &num[i].id, &num[i].value);
qsort(num, n, sizeof(num[0]), cmp);
for(int i = 0; i < n; i++)
printf("%d %lf\n", num[i].id, num[i].value);
return 0;
}
实际上的使用是对复杂的结构体类型排序的情况居多。掌握好 qsort()
对我们编写程序有很大的帮助。