comparison th_datastruct.c @ 759:618c7fa3a4f8

Add th_llist_mergesort() for sorting linked lists.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 05 Feb 2023 02:16:22 +0200
parents 72fb5ce9086a
children 2263dd13cf2d
comparison
equal deleted inserted replaced
758:72fb5ce9086a 759:618c7fa3a4f8
338 338
339 return NULL; 339 return NULL;
340 } 340 }
341 341
342 342
343 static th_llist_t *th_llist_mergesort_merge(th_llist_t *left, th_llist_t *right,
344 int (compare)(const th_llist_t *lnode, const th_llist_t *rnode, void *userdata),
345 void *userdata)
346 {
347 th_llist_t *result;
348
349 if (left == NULL)
350 return right;
351 else
352 if (right == NULL)
353 return left;
354
355 if (compare(left, right, userdata))
356 {
357 result = left;
358 result->next = th_llist_mergesort_merge(left->next, right, compare, userdata);
359 }
360 else
361 {
362 result = right;
363 result->next = th_llist_mergesort_merge(left, right->next, compare, userdata);
364 }
365
366 if (result->next != NULL)
367 result->prev = result->prev;
368
369 return result;
370 }
371
372
373 static void th_llist_mergesort_do(th_llist_t **list,
374 int (compare)(const th_llist_t *lnode, const th_llist_t *rnode, void *userdata),
375 void *userdata)
376 {
377 th_llist_t *head = *list, *left, *right, *slow, *fast;
378
379 if (head == NULL || head->next == NULL)
380 return;
381
382 slow = head;
383 fast = head->next;
384 while (fast != NULL)
385 {
386 fast = fast->next;
387 if (fast != NULL)
388 {
389 slow = slow->next;
390 fast = fast->next;
391 }
392 }
393
394 left = head;
395 right = slow->next;
396 slow->next = NULL;
397
398 th_llist_mergesort_do(&left, compare, userdata);
399 th_llist_mergesort_do(&right, compare, userdata);
400
401 *list = th_llist_mergesort_merge(left, right, compare, userdata);
402 }
403
404
405 void th_llist_mergesort(th_llist_t **list,
406 int (compare)(const th_llist_t *lnode, const th_llist_t *rnode, void *userdata),
407 void *userdata)
408 {
409 if (list != NULL && *list != NULL)
410 {
411 size_t num = (*list)->num;
412 th_llist_mergesort_do(list, compare, userdata);
413 (*list)->num = num;
414 }
415 }
416
417
343 /* 418 /*
344 * Ringbuffers 419 * Ringbuffers
345 */ 420 */
346 int th_ringbuf_init(th_ringbuf_t *buf, const size_t size, void (*mdeallocator)(void *data)) 421 int th_ringbuf_init(th_ringbuf_t *buf, const size_t size, void (*mdeallocator)(void *data))
347 { 422 {