排序算法在日常使用中很广泛,本篇首先关注 stdlib.h
里的快速排序 qsort
函数。具体的排序原理暂时按下不表,其平均时间复杂度为
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)。
qsort1
void qsort (void* base, size_t num, size_t size, int (*compar)(const void*, const void*));
四个参数分别是:
- 待排序数据的首地址
- 待排序数据的个数
- 待排序数据每个元素的大小,以字节计算。
- 排序函数,其返回值用于控制待排序数据排序后的放置顺序,从大到小还是从小到大。其原型为
int compar (const void* p1, const void* p2);
return value | meaning |
---|---|
< 0 | The element pointed to by p1 goes before the element pointed to by p2 |
0 | The element pointed to by p1 is equivalent to the element pointed to by p2 |
> 0 | The element pointed to by p1 goes after the element pointed to by p2 |
可知排序函数的返回值如果小于0,那么 p1 指向的元素放在 p2 指向的元素后。
元素可以是复合数据类型,比如结构体等,功能很强大,可以看到首地址和排序函数里的元素数据类型都是 (void *)
,正因为如此,才需要传入每个元素的大小用于找到下一个元素。
简单数据排序
/* qsort example */
#include <stdio.h> /* printf */
#include <stdlib.h> /* qsort */
#define ARR_SIZE(arr) (sizeof(arr)) / (sizeof(arr[0]))
int values[] = { 40, 10, 100, 90, 20, 25 };
int compare(const void * a, const void * b)
{
// 假如 *a > *b 返回 > 0 的话, 则 *a 放在 *b 后面,即从小到大排列。
return ( *(int*)a - *(int*)b );
}
int main(void)
{
int n;
qsort(values, ARR_SIZE(values), sizeof(int), compare);
for (n = 0; n < ARR_SIZE(values); n++) {
printf ("%d ",values[n]);
}
return 0;
}
输出为: 10 20 25 40 90 100
复杂数据排序
除比较整型等基本数据类型的一维数组外,二维数组,复合类型的数组也是能够比较的。只要修改 compare
函数中的实现。
// 先按 x 排,x 相同的情况下按 y 排,x 按升序,y 按降序
struct In {
int x;
int y;
} s[100];
int cmp(const void *a , const void *b)
{
struct In *c = (struct In *)a;
struct In *d = (struct In *)b;
if(c->x != d->x) {
return c->x - d->x;
} else {
return d->y - c->y;
}
}
http://www.cplusplus.com/reference/cstdlib/qsort/ ↩︎