3 <<qsort>>---sort an array
10 void qsort(void *<[base]>, size_t <[nmemb]>, size_t <[size]>,
11 int (*<[compar]>)(const void *, const void *) );
14 <<qsort>> sorts an array (beginning at <[base]>) of <[nmemb]> objects.
15 <[size]> describes the size of each element of the array.
17 You must supply a pointer to a comparison function, using the argument
18 shown as <[compar]>. (This permits sorting objects of unknown
19 properties.) Define the comparison function to accept two arguments,
20 each a pointer to an element of the array starting at <[base]>. The
21 result of <<(*<[compar]>)>> must be negative if the first argument is
22 less than the second, zero if the two arguments match, and positive if
23 the first argument is greater than the second (where ``less than'' and
24 ``greater than'' refer to whatever arbitrary ordering is appropriate).
26 The array is sorted in place; that is, when <<qsort>> returns, the
27 array elements beginning at <[base]> have been reordered.
30 <<qsort>> does not return a result.
33 <<qsort>> is required by ANSI (without specifying the sorting algorithm).
37 * Copyright (c) 1992, 1993
38 * The Regents of the University of California. All rights reserved.
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. Neither the name of the University nor the names of its contributors
49 * may be used to endorse or promote products derived from this software
50 * without specific prior written permission.
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66 #include <sys/cdefs.h>
73 #if defined(I_AM_QSORT_R)
74 typedef int cmp_t(void *, const void *, const void *);
75 #elif defined(I_AM_GNU_QSORT_R)
76 typedef int cmp_t(const void *, const void *, void *);
78 typedef int cmp_t(const void *, const void *);
80 static inline char *med3 (char *, char *, char *, cmp_t
*, void *);
81 static inline void swapfunc (char *, char *, int, int);
83 #define min(a, b) (a) < (b) ? a : b
86 * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
88 #define swapcode(TYPE, parmi, parmj, n) { \
89 long i = (n) / sizeof (TYPE); \
90 TYPE *pi = (TYPE *) (parmi); \
91 TYPE *pj = (TYPE *) (parmj); \
99 #define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
100 es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
109 swapcode(long, a
, b
, n
)
111 swapcode(char, a
, b
, n
)
115 if (swaptype == 0) { \
116 long t = *(long *)(a); \
117 *(long *)(a) = *(long *)(b); \
120 swapfunc(a, b, es, swaptype)
122 #define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
124 #if defined(I_AM_QSORT_R)
125 #define CMP(t, x, y) (cmp((t), (x), (y)))
126 #elif defined(I_AM_GNU_QSORT_R)
127 #define CMP(t, x, y) (cmp((x), (y), (t)))
129 #define CMP(t, x, y) (cmp((x), (y)))
138 #if !defined(I_AM_QSORT_R) && !defined(I_AM_GNU_QSORT_R)
143 return CMP(thunk
, a
, b
) < 0 ?
144 (CMP(thunk
, b
, c
) < 0 ? b
: (CMP(thunk
, a
, c
) < 0 ? c
: a
))
145 :(CMP(thunk
, b
, c
) > 0 ? b
: (CMP(thunk
, a
, c
) < 0 ? a
: c
));
149 * Classical function call recursion wastes a lot of stack space. Each
150 * recursion level requires a full stack frame comprising all local variables
151 * and additional space as dictated by the processor calling convention.
153 * This implementation instead stores the variables that are unique for each
154 * recursion level in a parameter stack array, and uses iteration to emulate
155 * recursion. Function call recursion is not used until the array is full.
157 * To ensure the stack consumption isn't worsened by this design, the size of
158 * the parameter stack array is chosen to be similar to the stack frame
159 * excluding the array. Each function call recursion level can handle this
160 * number of iterative recursion levels.
162 #define PARAMETER_STACK_LEVELS 8u
164 #if defined(I_AM_QSORT_R)
166 __bsd_qsort_r (void *a
,
171 #elif defined(I_AM_GNU_QSORT_R)
187 char *pa
, *pb
, *pc
, *pd
, *pl
, *pm
, *pn
;
190 int swaptype
, swap_cnt
;
191 size_t recursion_level
= 0;
192 struct { void *a
; size_t n
; } parameter_stack
[PARAMETER_STACK_LEVELS
];
197 /* Short arrays are insertion sorted. */
198 for (pm
= (char *) a
+ es
; pm
< (char *) a
+ n
* es
; pm
+= es
)
199 for (pl
= pm
; pl
> (char *) a
&& CMP(thunk
, pl
- es
, pl
) > 0;
205 /* Select a pivot element, move it to the left. */
206 pm
= (char *) a
+ (n
/ 2) * es
;
209 pn
= (char *) a
+ (n
- 1) * es
;
212 pl
= med3(pl
, pl
+ d
, pl
+ 2 * d
, cmp
, thunk
);
213 pm
= med3(pm
- d
, pm
, pm
+ d
, cmp
, thunk
);
214 pn
= med3(pn
- 2 * d
, pn
- d
, pn
, cmp
, thunk
);
216 pm
= med3(pl
, pm
, pn
, cmp
, thunk
);
221 * Sort the array relative the pivot in four ranges as follows:
222 * { elems == pivot, elems < pivot, elems > pivot, elems == pivot }
224 pa
= pb
= (char *) a
+ es
;
225 pc
= pd
= (char *) a
+ (n
- 1) * es
;
227 /* Scan left to right stopping at first element > pivot. */
228 while (pb
<= pc
&& (cmp_result
= CMP(thunk
, pb
, a
)) <= 0) {
229 /* Move elements == pivot to the left (to pa) */
230 if (cmp_result
== 0) {
237 /* Scan right to left stopping at first element < pivot. */
238 while (pb
<= pc
&& (cmp_result
= CMP(thunk
, pc
, a
)) >= 0) {
239 /* Move elements == pivot to the right (to pd) */
240 if (cmp_result
== 0) {
249 /* The scan has found two elements to swap with each other. */
255 if (swap_cnt
== 0) { /* Switch to insertion sort */
256 for (pm
= (char *) a
+ es
; pm
< (char *) a
+ n
* es
; pm
+= es
)
257 for (pl
= pm
; pl
> (char *) a
&& CMP(thunk
, pl
- es
, pl
) > 0;
264 * Rearrange the array in three parts sorted like this:
265 * { elements < pivot, elements == pivot, elements > pivot }
267 pn
= (char *) a
+ n
* es
;
268 r
= min(pa
- (char *)a
, pb
- pa
);
269 vecswap(a
, pb
- r
, r
);
270 r
= min(pd
- pc
, pn
- pd
- es
);
271 vecswap(pb
, pn
- r
, r
);
272 d
= pb
- pa
; /* d = Size of left part. */
273 r
= pd
- pc
; /* r = Size of right part. */
274 pn
-= r
; /* pn = Base of right part. */
277 * Check which of the left and right parts are larger.
278 * Set (a, n) to (base, size) of the larger part.
279 * Set (pa, r) to (base, size) of the smaller part.
281 if (r
> d
) { /* Right part is the larger part */
287 else { /* Left part is the larger part, or both are equal. */
293 * The left and right parts each need further sorting if they
294 * contain two elements or more. If both need sorting we use
295 * recursion to sort the smaller part and save the larger part
296 * to be sorted by iteration after the recursion.
297 * Using recursion only for the smaller part guarantees a
298 * recursion depth that is bounded to be less than (log2(n)).
300 if (r
> es
) { /* Smaller part > 1 element. Both parts need sorting. */
301 if (recursion_level
< PARAMETER_STACK_LEVELS
) {
303 * The smaller part needs to be recursively sorted
304 * before the larger part is sorted. To avoid function
305 * call recursion the parameters for the larger part
306 * are pushed on the parameter_stack array. The smaller
307 * part is sorted using iteration and the larger part
308 * will be sorted when the parameter_stack is popped
309 * after the smaller part has been sorted.
311 parameter_stack
[recursion_level
].a
= a
;
312 parameter_stack
[recursion_level
].n
= n
/ es
;
320 * The parameter_stack array is full. The smaller part
321 * is sorted using function call recursion. The larger
322 * part will be sorted after the function call returns.
324 #if defined(I_AM_QSORT_R)
325 __bsd_qsort_r(pa
, r
/ es
, es
, thunk
, cmp
);
326 #elif defined(I_AM_GNU_QSORT_R)
327 qsort_r(pa
, r
/ es
, es
, cmp
, thunk
);
329 qsort(pa
, r
/ es
, es
, cmp
);
333 if (n
> es
) { /* The larger part needs sorting. Iterate to sort. */
337 /* Both left and right parts are one element or less - level done. */
339 if (recursion_level
!= 0) {
341 a
= parameter_stack
[recursion_level
].a
;
342 n
= parameter_stack
[recursion_level
].n
;