diff options
Diffstat (limited to 'arraylist.c')
| -rw-r--r-- | arraylist.c | 90 |
1 files changed, 81 insertions, 9 deletions
diff --git a/arraylist.c b/arraylist.c index 420dc0b..668278e 100644 --- a/arraylist.c +++ b/arraylist.c | |||
| @@ -160,22 +160,22 @@ ArrayList_removeAt(struct ArrayList *arrayList, size_t idx, void clear_func(T *, | |||
| 160 | --arrayList->size; | 160 | --arrayList->size; |
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | struct ArrayList_sort_ctx { | 163 | struct qsortHelper_context { |
| 164 | int (*cmp)(const T *, const T *, void *); | 164 | int (*cmp)(const T *, const T *, void *); |
| 165 | void *args; | 165 | void *args; |
| 166 | }; | 166 | }; |
| 167 | 167 | ||
| 168 | typedef const T *const_ptr; | 168 | typedef const T *const_T_ptr; |
| 169 | 169 | ||
| 170 | static int | 170 | static int |
| 171 | ArrayList_compareAdapter(void *ctx, const void *a, const void *b) | 171 | ArrayList_qsortHelper(void *ctx, const void *a, const void *b) |
| 172 | { | 172 | { |
| 173 | const const_ptr *aa = a; | 173 | const const_T_ptr *aa = a; |
| 174 | const const_ptr *bb = b; | 174 | const const_T_ptr *bb = b; |
| 175 | 175 | ||
| 176 | const struct ArrayList_sort_ctx *sort_ctx = ctx; | 176 | const struct qsortHelper_context *context = ctx; |
| 177 | 177 | ||
| 178 | return sort_ctx->cmp(*aa, *bb, sort_ctx->args); | 178 | return context->cmp(*aa, *bb, context->args); |
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | void | 181 | void |
| @@ -184,12 +184,65 @@ ArrayList_sort(struct ArrayList *arrayList, int cmp(const T *, const T *, void * | |||
| 184 | assert(arrayList != NULL); | 184 | assert(arrayList != NULL); |
| 185 | assert(cmp != NULL); | 185 | assert(cmp != NULL); |
| 186 | 186 | ||
| 187 | struct ArrayList_sort_ctx sort_ctx = { | 187 | struct qsortHelper_context context = { |
| 188 | .cmp = cmp, | 188 | .cmp = cmp, |
| 189 | .args = args | 189 | .args = args |
| 190 | }; | 190 | }; |
| 191 | 191 | ||
| 192 | qsort_r(arrayList->array, arrayList->size, sizeof(arrayList->array[0]), &sort_ctx, ArrayList_compareAdapter); | 192 | // Das vollständige qsort_x()-Drama: https://stackoverflow.com/a/46042467 |
| 193 | qsort_r(arrayList->array, arrayList->size, sizeof(arrayList->array[0]), &context, ArrayList_qsortHelper); | ||
| 194 | } | ||
| 195 | |||
| 196 | bool | ||
| 197 | ArrayList_linearSearch(struct ArrayList *arrayList, void *key, int cmp(void *, const T *), size_t *loc) | ||
| 198 | { | ||
| 199 | assert(arrayList != NULL); | ||
| 200 | assert(cmp != NULL); | ||
| 201 | assert(loc != NULL); | ||
| 202 | |||
| 203 | for ( size_t idx = 0; idx != arrayList->size; ++idx ) { | ||
| 204 | if ( cmp(key, arrayList->array[idx]) == 0 ) { | ||
| 205 | *loc = idx; | ||
| 206 | return true; | ||
| 207 | } | ||
| 208 | } | ||
| 209 | return false; | ||
| 210 | } | ||
| 211 | |||
| 212 | struct bsearchHelper_context { | ||
| 213 | void *key; | ||
| 214 | int (*cmp)(void *, const T *); | ||
| 215 | }; | ||
| 216 | |||
| 217 | static int | ||
| 218 | ArrayList_bsearchHelper(const void *ctx, const void *el) | ||
| 219 | { | ||
| 220 | const struct bsearchHelper_context *context = ctx; | ||
| 221 | const const_T_ptr * element = el; | ||
| 222 | |||
| 223 | return context->cmp(context->key, *element); | ||
| 224 | } | ||
| 225 | |||
| 226 | bool | ||
| 227 | ArrayList_binarySearch(struct ArrayList *arrayList, void *key, int cmp(void *, const T *), size_t *loc) | ||
| 228 | { | ||
| 229 | assert(arrayList != NULL); | ||
| 230 | assert(cmp != NULL); | ||
| 231 | assert(loc != NULL); | ||
| 232 | |||
| 233 | struct bsearchHelper_context context = { | ||
| 234 | .key = key, | ||
| 235 | .cmp = cmp | ||
| 236 | }; | ||
| 237 | |||
| 238 | T **pos = bsearch(&context, arrayList->array, arrayList->size, sizeof(arrayList->array[0]), ArrayList_bsearchHelper); | ||
| 239 | if ( pos != NULL ) { | ||
| 240 | *loc = (size_t)(pos - arrayList->array); | ||
| 241 | return true; | ||
| 242 | } | ||
| 243 | else { | ||
| 244 | return false; | ||
| 245 | } | ||
| 193 | } | 246 | } |
| 194 | 247 | ||
| 195 | void | 248 | void |
| @@ -236,6 +289,19 @@ my_compare(const T *a, const T *b, void *args) | |||
| 236 | } | 289 | } |
| 237 | } | 290 | } |
| 238 | 291 | ||
| 292 | static int | ||
| 293 | my_search_compare(void *key, const T *element) | ||
| 294 | { | ||
| 295 | int *a = key; | ||
| 296 | |||
| 297 | if ( *a < *element ) | ||
| 298 | return -1; | ||
| 299 | else if ( *a > *element ) | ||
| 300 | return 1; | ||
| 301 | else | ||
| 302 | return 0; | ||
| 303 | } | ||
| 304 | |||
| 239 | static size_t | 305 | static size_t |
| 240 | my_rng(size_t max, void *args) | 306 | my_rng(size_t max, void *args) |
| 241 | { | 307 | { |
| @@ -280,6 +346,12 @@ main(void) | |||
| 280 | 346 | ||
| 281 | ArrayList_debugPrint(arrayList); // 11, 22, 33, 44 | 347 | ArrayList_debugPrint(arrayList); // 11, 22, 33, 44 |
| 282 | 348 | ||
| 349 | size_t loc; | ||
| 350 | int dummy = 44; | ||
| 351 | if ( ArrayList_binarySearch(arrayList, &dummy, my_search_compare, &loc) ) { | ||
| 352 | printf("Gefunden: %zu\n", loc); | ||
| 353 | } | ||
| 354 | |||
| 283 | ArrayList_shuffle(arrayList, my_rng, NULL); | 355 | ArrayList_shuffle(arrayList, my_rng, NULL); |
| 284 | ArrayList_debugPrint(arrayList); // ?? | 356 | ArrayList_debugPrint(arrayList); // ?? |
| 285 | 357 | ||
