7 /* Converts a string representation of a signed decimal integer
8 in S into an `int', which is returned. */
17 /* Skip white space. */
18 while (isspace ((unsigned char) *s))
31 /* Parse digits. We always initially parse the value as
32 negative, and then make it positive later, because the
33 negative range of an int is bigger than the positive range
34 on a 2's complement system. */
35 for (value = 0; isdigit (*s); s++)
36 value = value * 10 - (*s - '0');
43 /* Compares A and B by calling the AUX function. */
45 compare_thunk (const void *a, const void *b, void *aux)
47 int (**compare) (const void *, const void *) = aux;
48 return (*compare) (a, b);
51 /* Sorts ARRAY, which contains CNT elements of SIZE bytes each,
52 using COMPARE. When COMPARE is passed a pair of elements A
53 and B, respectively, it must return a strcmp()-type result,
54 i.e. less than zero if A < B, zero if A == B, greater than
57 qsort (void *array, size_t cnt, size_t size,
58 int (*compare) (const void *, const void *))
60 quick_sort (array, cnt, size, compare_thunk, &compare);
63 /* Swaps the SIZE bytes at A and B. */
65 swap (unsigned char *a, unsigned char *b, size_t size)
69 for (i = 0; i < size; i++)
71 unsigned char t = a[i];
77 /* Selects a random "pivot" element in ARRAY, which contains CNT
78 elements of SIZE bytes each, and partitions ARRAY into two
79 contiguous subranges around the pivot, so that the first N
80 elements are less than or equal to the pivot and the remaining
81 elements are greater than the pivot. Returns N.
83 Uses COMPARE to compare elements, passing AUX as auxiliary
84 data. When COMPARE is passed a pair of elements A and B,
85 respectively, it must return a strcmp()-type result, i.e. less
86 than zero if A < B, zero if A == B, greater than zero if A >
89 randomized_partition (void *array, size_t cnt, size_t size,
90 int (*compare) (const void *, const void *, void *aux),
93 unsigned char *first = array; /* Beginning of array. */
94 unsigned char *last = first + size * cnt; /* End of array. */
95 unsigned char *pivot = last - size; /* Element used as pivot. */
96 unsigned char *middle; /* Invariant: elements on left are <= pivot. */
97 unsigned char *current;
99 ASSERT (array != NULL);
102 ASSERT (compare != NULL);
104 /* Choose a random pivot. */
105 swap (pivot, first + (random_ulong () % cnt) * size, size);
107 /* Iterate through the array moving elements less than or equal
108 to the pivot to the middle. */
110 for (current = first; current < last; current += size)
111 if (compare (current, pivot, aux) <= 0)
113 swap (middle, current, size);
117 return (middle - first) / size;
120 /* Sorts ARRAY, which contains CNT elements of SIZE bytes each,
121 using COMPARE to compare elements, passing AUX as auxiliary
122 data. When COMPARE is passed a pair of elements A and B,
123 respectively, it must return a strcmp()-type result, i.e. less
124 than zero if A < B, zero if A == B, greater than zero if A >
127 quick_sort (void *array_, size_t cnt, size_t size,
128 int (*compare) (const void *, const void *, void *aux),
131 unsigned char *array = array_;
133 ASSERT (array != NULL || cnt == 0);
134 ASSERT (compare != NULL);
139 size_t q = randomized_partition (array, cnt, size, compare, aux);
141 /* Sort smaller partition first to guarantee O(lg n) stack
145 quick_sort (array, q, size, compare, aux);
146 quick_sort (array + q * size, cnt - q, size, compare, aux);
150 quick_sort (array + q * size, cnt - q, size, compare, aux);
151 quick_sort (array, q, size, compare, aux);
156 /* Searches ARRAY, which contains CNT elements of SIZE bytes
157 each, for the given KEY. Returns a match is found, otherwise
158 a null pointer. If there are multiple matches, returns an
159 arbitrary one of them.
161 ARRAY must be sorted in order according to COMPARE.
163 Uses COMPARE to compare elements. When COMPARE is passed a
164 pair of elements A and B, respectively, it must return a
165 strcmp()-type result, i.e. less than zero if A < B, zero if A
166 == B, greater than zero if A > B. */
168 bsearch (const void *key, const void *array, size_t cnt,
169 size_t size, int (*compare) (const void *, const void *))
171 return binary_search (key, array, cnt, size, compare_thunk, &compare);
174 /* Searches ARRAY, which contains CNT elements of SIZE bytes
175 each, for the given KEY. Returns a match is found, otherwise
176 a null pointer. If there are multiple matches, returns an
177 arbitrary one of them.
179 ARRAY must be sorted in order according to COMPARE.
181 Uses COMPARE to compare elements, passing AUX as auxiliary
182 data. When COMPARE is passed a pair of elements A and B,
183 respectively, it must return a strcmp()-type result, i.e. less
184 than zero if A < B, zero if A == B, greater than zero if A >
187 binary_search (const void *key, const void *array, size_t cnt, size_t size,
188 int (*compare) (const void *, const void *, void *aux),
191 const unsigned char *first = array;
192 const unsigned char *last = array + size * cnt;
196 size_t range = (last - first) / size;
197 const unsigned char *middle = first + (range / 2) * size;
198 int cmp = compare (key, middle, aux);
203 first = middle + size;
205 return (void *) middle;