-
Notifications
You must be signed in to change notification settings - Fork 16
/
qsort.c
48 lines (43 loc) · 908 Bytes
/
qsort.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/* based on musl libc's qsort.c */
#include <stdlib.h>
#include <string.h>
#define MIN(a, b) ((a) < (b) ? (a) : (b))
static void swap(char *a, char *b, int sz)
{
char tmp[256];
while (sz) {
int l = MIN(sizeof(tmp), sz);
memcpy(tmp, a, l);
memcpy(a, b, l);
memcpy(b, tmp, l);
a += l;
b += l;
sz -= l;
}
}
static void fix(char *a, int root, int n, int sz, int (*cmp)(void *, void *))
{
while (2 * root <= n) {
int max = 2 * root;
if (max < n && cmp(a + max * sz, a + (max + 1) * sz) < 0)
max++;
if (max && cmp(a + root * sz, a + max * sz) < 0) {
swap(a + root * sz, a + max * sz, sz);
root = max;
} else {
break;
}
}
}
void qsort(void *a, int n, int sz, int (*cmp)(void *, void *))
{
int i;
if (!n)
return;
for (i = (n + 1) >> 1; i; i--)
fix(a, i - 1, n - 1, sz, cmp);
for (i = n - 1; i; i--) {
swap(a, a + i * sz, sz);
fix(a, 0, i - 1, sz, cmp);
}
}