tdelete.c 1003 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. #include <stdlib.h>
  2. #include <search.h>
  3. #include "tsearch.h"
  4. void *tdelete(const void *restrict key, void **restrict rootp,
  5. int(*cmp)(const void *, const void *))
  6. {
  7. if (!rootp)
  8. return 0;
  9. void **a[MAXH+1];
  10. struct node *n = *rootp;
  11. struct node *parent;
  12. struct node *child;
  13. int i=0;
  14. /* *a[0] is an arbitrary non-null pointer that is returned when
  15. the root node is deleted. */
  16. a[i++] = rootp;
  17. a[i++] = rootp;
  18. for (;;) {
  19. if (!n)
  20. return 0;
  21. int c = cmp(key, n->key);
  22. if (!c)
  23. break;
  24. a[i++] = &n->a[c>0];
  25. n = n->a[c>0];
  26. }
  27. parent = *a[i-2];
  28. if (n->a[0]) {
  29. /* free the preceding node instead of the deleted one. */
  30. struct node *deleted = n;
  31. a[i++] = &n->a[0];
  32. n = n->a[0];
  33. while (n->a[1]) {
  34. a[i++] = &n->a[1];
  35. n = n->a[1];
  36. }
  37. deleted->key = n->key;
  38. child = n->a[0];
  39. } else {
  40. child = n->a[1];
  41. }
  42. /* freed node has at most one child, move it up and rebalance. */
  43. free(n);
  44. *a[--i] = child;
  45. while (--i && __tsearch_balance(a[i]));
  46. return parent;
  47. }