diff options
author | millert <> | 2017-05-22 17:16:43 +0000 |
---|---|---|
committer | millert <> | 2017-05-22 17:16:43 +0000 |
commit | 4e24c3e353b3352f5eee42455b8322da5be0718d (patch) | |
tree | 76e2b3c306921bf06b7a7bd7224ac229b239cf24 /src/regress/lib/libc/qsort/antiqsort.c | |
parent | cd02cea116f8f7023f94aea2cfd0cee48622e91f (diff) | |
download | openbsd-4e24c3e353b3352f5eee42455b8322da5be0718d.tar.gz openbsd-4e24c3e353b3352f5eee42455b8322da5be0718d.tar.bz2 openbsd-4e24c3e353b3352f5eee42455b8322da5be0718d.zip |
Instead of embedding pre-generated tables from McIlroy's "A Killer
Adversary for Quicksort", just include the code to generate them.
Also allow the number of elements to be specified on the command line.
Diffstat (limited to 'src/regress/lib/libc/qsort/antiqsort.c')
-rw-r--r-- | src/regress/lib/libc/qsort/antiqsort.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/regress/lib/libc/qsort/antiqsort.c b/src/regress/lib/libc/qsort/antiqsort.c new file mode 100644 index 0000000000..cb3b7b2525 --- /dev/null +++ b/src/regress/lib/libc/qsort/antiqsort.c | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * A Killer Adversary for Quicksort | ||
3 | * M. D. MCILROY | ||
4 | * http://www.cs.dartmouth.edu/~doug/mdmspe.pdf | ||
5 | * | ||
6 | * For comparison: | ||
7 | * Bentley & McIlroy: 4096 items, 1645585 compares | ||
8 | * random pivot: 4096 items, 8388649 compares | ||
9 | * introsort: 4096 items, 151580 compares | ||
10 | * heapsort: 4096 items, 48233 compares | ||
11 | */ | ||
12 | |||
13 | #include <stdio.h> | ||
14 | #include <stdlib.h> | ||
15 | |||
16 | static int *val; /* item values */ | ||
17 | static int ncmp; /* number of comparisons */ | ||
18 | static int nsolid; /* number of solid items */ | ||
19 | static int candidate; /* pivot candidate */ | ||
20 | static int gas; /* gas value */ | ||
21 | |||
22 | #define freeze(x) (val[(x)] = nsolid++) | ||
23 | |||
24 | static int | ||
25 | cmp(const void *px, const void *py) | ||
26 | { | ||
27 | const int x = *(const int *)px; | ||
28 | const int y = *(const int *)py; | ||
29 | |||
30 | ncmp++; | ||
31 | if (val[x] == gas && val[y] == gas) { | ||
32 | if (x == candidate) | ||
33 | freeze(x); | ||
34 | else | ||
35 | freeze(y); | ||
36 | } | ||
37 | if (val[x] == gas) | ||
38 | candidate = x; | ||
39 | else if (val[y] == gas) | ||
40 | candidate = y; | ||
41 | return val[x] > val[y] ? 1 : val[x] < val[y] ? -1 : 0; | ||
42 | } | ||
43 | |||
44 | int | ||
45 | antiqsort(int n, int *a, int *ptr) | ||
46 | { | ||
47 | int i; | ||
48 | |||
49 | val = a; | ||
50 | gas = n - 1; | ||
51 | nsolid = ncmp = candidate = 0; | ||
52 | for (i = 0; i < n; i++) { | ||
53 | ptr[i] = i; | ||
54 | val[i] = gas; | ||
55 | } | ||
56 | qsort(ptr, n, sizeof(*ptr), cmp); | ||
57 | return ncmp; | ||
58 | } | ||