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