3 <<qsort>>---sort an array
10 void qsort(void *<[base]>, size_t <[nmemb]>, size_t <[size]>,
11 int (*<[compar]>)(const void *, const void *) );
15 qsort(<[base]>, <[nmemb]>, <[size]>, <[compar]> )
22 <<qsort>> sorts an array (beginning at <[base]>) of <[nmemb]> objects.
23 <[size]> describes the size of each element of the array.
25 You must supply a pointer to a comparison function, using the argument
26 shown as <[compar]>. (This permits sorting objects of unknown
27 properties.) Define the comparison function to accept two arguments,
28 each a pointer to an element of the array starting at <[base]>. The
29 result of <<(*<[compar]>)>> must be negative if the first argument is
30 less than the second, zero if the two arguments match, and positive if
31 the first argument is greater than the second (where ``less than'' and
32 ``greater than'' refer to whatever arbitrary ordering is appropriate).
34 The array is sorted in place; that is, when <<qsort>> returns, the
35 array elements beginning at <[base]> have been reordered.
38 <<qsort>> does not return a result.
41 <<qsort>> is required by ANSI (without specifying the sorting algorithm).
45 * Copyright (c) 1992, 1993
46 * The Regents of the University of California. All rights reserved.
48 * Redistribution and use in source and binary forms, with or without
49 * modification, are permitted provided that the following conditions
51 * 1. Redistributions of source code must retain the above copyright
52 * notice, this list of conditions and the following disclaimer.
53 * 2. Redistributions in binary form must reproduce the above copyright
54 * notice, this list of conditions and the following disclaimer in the
55 * documentation and/or other materials provided with the distribution.
56 * 3. All advertising materials mentioning features or use of this software
57 * must display the following acknowledgement:
58 * This product includes software developed by the University of
59 * California, Berkeley and its contributors.
60 * 4. Neither the name of the University nor the names of its contributors
61 * may be used to endorse or promote products derived from this software
62 * without specific prior written permission.
64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
84 static inline char *med3
_PARAMS((char *, char *, char *, int (*cmp
)(const _PTR
,const _PTR
)));
85 static inline void swapfunc
_PARAMS((char *, char *, int, int));
87 #define min(a, b) (a) < (b) ? a : b
90 * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
92 #define swapcode(TYPE, parmi, parmj, n) { \
93 long i = (n) / sizeof (TYPE); \
94 register TYPE *pi = (TYPE *) (parmi); \
95 register TYPE *pj = (TYPE *) (parmj); \
97 register TYPE t = *pi; \
103 #define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
104 es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
107 _DEFUN(swapfunc
, (a
, b
, n
, swaptype
),
114 swapcode(long, a
, b
, n
)
116 swapcode(char, a
, b
, n
)
120 if (swaptype == 0) { \
121 long t = *(long *)(a); \
122 *(long *)(a) = *(long *)(b); \
125 swapfunc(a, b, es, swaptype)
127 #define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
130 _DEFUN(med3
, (a
, b
, c
, cmp
),
134 int (*cmp
)(const _PTR
,const _PTR
))
136 return cmp(a
, b
) < 0 ?
137 (cmp(b
, c
) < 0 ? b
: (cmp(a
, c
) < 0 ? c
: a
))
138 :(cmp(b
, c
) > 0 ? b
: (cmp(a
, c
) < 0 ? a
: c
));
142 _DEFUN(qsort
, (a
, n
, es
, cmp
),
146 int (*cmp
)(const _PTR
,const _PTR
))
148 char *pa
, *pb
, *pc
, *pd
, *pl
, *pm
, *pn
;
149 int d
, r
, swaptype
, swap_cnt
;
151 loop
: SWAPINIT(a
, es
);
154 for (pm
= (char *) a
+ es
; pm
< (char *) a
+ n
* es
; pm
+= es
)
155 for (pl
= pm
; pl
> (char *) a
&& cmp(pl
- es
, pl
) > 0;
160 pm
= (char *) a
+ (n
/ 2) * es
;
163 pn
= (char *) a
+ (n
- 1) * es
;
166 pl
= med3(pl
, pl
+ d
, pl
+ 2 * d
, cmp
);
167 pm
= med3(pm
- d
, pm
, pm
+ d
, cmp
);
168 pn
= med3(pn
- 2 * d
, pn
- d
, pn
, cmp
);
170 pm
= med3(pl
, pm
, pn
, cmp
);
173 pa
= pb
= (char *) a
+ es
;
175 pc
= pd
= (char *) a
+ (n
- 1) * es
;
177 while (pb
<= pc
&& (r
= cmp(pb
, a
)) <= 0) {
185 while (pb
<= pc
&& (r
= cmp(pc
, a
)) >= 0) {
200 if (swap_cnt
== 0) { /* Switch to insertion sort */
201 for (pm
= (char *) a
+ es
; pm
< (char *) a
+ n
* es
; pm
+= es
)
202 for (pl
= pm
; pl
> (char *) a
&& cmp(pl
- es
, pl
) > 0;
208 pn
= (char *) a
+ n
* es
;
209 r
= min(pa
- (char *)a
, pb
- pa
);
210 vecswap(a
, pb
- r
, r
);
211 r
= min((unsigned int)(pd
- pc
), pn
- pd
- es
);
212 vecswap(pb
, pn
- r
, r
);
213 if ((unsigned int)(r
= pb
- pa
) > es
)
214 qsort(a
, r
/ es
, es
, cmp
);
215 if ((unsigned int)(r
= pd
- pc
) > es
) {
216 /* Iterate rather than recurse to save stack space */
221 /* qsort(pn - r, r / es, es, cmp);*/