1*e17fe16cSchristos /* $NetBSD: tdelete.c,v 1.8 2016/01/20 20:47:41 christos Exp $ */
27975455dSchristos
37975455dSchristos /*
47975455dSchristos * Tree search generalized from Knuth (6.2.2) Algorithm T just like
57975455dSchristos * the AT&T man page says.
67975455dSchristos *
77975455dSchristos * The node_t structure is for internal use only, lint doesn't grok it.
87975455dSchristos *
97975455dSchristos * Written by reading the System V Interface Definition, not the code.
107975455dSchristos *
117975455dSchristos * Totally public domain.
127975455dSchristos */
137975455dSchristos
147975455dSchristos #include <sys/cdefs.h>
157975455dSchristos #if defined(LIBC_SCCS) && !defined(lint)
16*e17fe16cSchristos __RCSID("$NetBSD: tdelete.c,v 1.8 2016/01/20 20:47:41 christos Exp $");
177975455dSchristos #endif /* LIBC_SCCS and not lint */
187975455dSchristos
19b48252f3Slukem #include <assert.h>
207975455dSchristos #define _SEARCH_PRIVATE
217975455dSchristos #include <search.h>
227975455dSchristos #include <stdlib.h>
237975455dSchristos
247975455dSchristos
259e66e6d7Sabs /* find a node with key "vkey" in tree "vrootp" */
267975455dSchristos void *
tdelete(const void * vkey,void ** vrootp,int (* compar)(const void *,const void *))279e66e6d7Sabs tdelete(const void *vkey, void **vrootp,
289e66e6d7Sabs int (*compar)(const void *, const void *))
297975455dSchristos {
307975455dSchristos node_t **rootp = (node_t **)vrootp;
317975455dSchristos node_t *p, *q, *r;
327975455dSchristos int cmp;
337975455dSchristos
34b48252f3Slukem _DIAGASSERT(vkey != NULL);
35b48252f3Slukem _DIAGASSERT(compar != NULL);
36b48252f3Slukem
377975455dSchristos if (rootp == NULL || (p = *rootp) == NULL)
387975455dSchristos return NULL;
397975455dSchristos
407975455dSchristos while ((cmp = (*compar)(vkey, (*rootp)->key)) != 0) {
417975455dSchristos p = *rootp;
427975455dSchristos rootp = (cmp < 0) ?
437975455dSchristos &(*rootp)->llink : /* follow llink branch */
447975455dSchristos &(*rootp)->rlink; /* follow rlink branch */
457975455dSchristos if (*rootp == NULL)
467975455dSchristos return NULL; /* key not found */
477975455dSchristos }
487975455dSchristos r = (*rootp)->rlink; /* D1: */
497975455dSchristos if ((q = (*rootp)->llink) == NULL) /* Left NULL? */
507975455dSchristos q = r;
517975455dSchristos else if (r != NULL) { /* Right link is NULL? */
527975455dSchristos if (r->llink == NULL) { /* D2: Find successor */
537975455dSchristos r->llink = q;
547975455dSchristos q = r;
557975455dSchristos } else { /* D3: Find NULL link */
567975455dSchristos for (q = r->llink; q->llink != NULL; q = r->llink)
577975455dSchristos r = q;
587975455dSchristos r->llink = q->rlink;
597975455dSchristos q->llink = (*rootp)->llink;
607975455dSchristos q->rlink = (*rootp)->rlink;
617975455dSchristos }
627975455dSchristos }
637975455dSchristos free(*rootp); /* D4: Free node */
647975455dSchristos *rootp = q; /* link parent to new node */
657975455dSchristos return p;
667975455dSchristos }
67