164566a3eSAlfred Perlstein /* $NetBSD: tdelete.c,v 1.2 1999/09/16 11:45:37 lukem Exp $ */ 264566a3eSAlfred Perlstein /* $FreeBSD$ */ 364566a3eSAlfred Perlstein 464566a3eSAlfred Perlstein /* 564566a3eSAlfred Perlstein * Tree search generalized from Knuth (6.2.2) Algorithm T just like 664566a3eSAlfred Perlstein * the AT&T man page says. 764566a3eSAlfred Perlstein * 864566a3eSAlfred Perlstein * The node_t structure is for internal use only, lint doesn't grok it. 964566a3eSAlfred Perlstein * 1064566a3eSAlfred Perlstein * Written by reading the System V Interface Definition, not the code. 1164566a3eSAlfred Perlstein * 1264566a3eSAlfred Perlstein * Totally public domain. 1364566a3eSAlfred Perlstein */ 1464566a3eSAlfred Perlstein 1564566a3eSAlfred Perlstein #include <sys/cdefs.h> 1664566a3eSAlfred Perlstein #if defined(LIBC_SCCS) && !defined(lint) 1764566a3eSAlfred Perlstein __RCSID("$NetBSD: tdelete.c,v 1.2 1999/09/16 11:45:37 lukem Exp $"); 1864566a3eSAlfred Perlstein #endif /* LIBC_SCCS and not lint */ 1964566a3eSAlfred Perlstein 2064566a3eSAlfred Perlstein #include <assert.h> 2164566a3eSAlfred Perlstein #define _SEARCH_PRIVATE 2264566a3eSAlfred Perlstein #include <search.h> 2364566a3eSAlfred Perlstein #include <stdlib.h> 2464566a3eSAlfred Perlstein 2564566a3eSAlfred Perlstein 2664566a3eSAlfred Perlstein /* delete node with given key */ 2764566a3eSAlfred Perlstein void * 2864566a3eSAlfred Perlstein tdelete(vkey, vrootp, compar) 2964566a3eSAlfred Perlstein const void *vkey; /* key to be deleted */ 3064566a3eSAlfred Perlstein void **vrootp; /* address of the root of tree */ 3164566a3eSAlfred Perlstein int (*compar) __P((const void *, const void *)); 3264566a3eSAlfred Perlstein { 3364566a3eSAlfred Perlstein node_t **rootp = (node_t **)vrootp; 3464566a3eSAlfred Perlstein node_t *p, *q, *r; 3564566a3eSAlfred Perlstein int cmp; 3664566a3eSAlfred Perlstein 3764566a3eSAlfred Perlstein if (rootp == NULL || (p = *rootp) == NULL) 3864566a3eSAlfred Perlstein return NULL; 3964566a3eSAlfred Perlstein 4064566a3eSAlfred Perlstein while ((cmp = (*compar)(vkey, (*rootp)->key)) != 0) { 4164566a3eSAlfred Perlstein p = *rootp; 4264566a3eSAlfred Perlstein rootp = (cmp < 0) ? 4364566a3eSAlfred Perlstein &(*rootp)->llink : /* follow llink branch */ 4464566a3eSAlfred Perlstein &(*rootp)->rlink; /* follow rlink branch */ 4564566a3eSAlfred Perlstein if (*rootp == NULL) 4664566a3eSAlfred Perlstein return NULL; /* key not found */ 4764566a3eSAlfred Perlstein } 4864566a3eSAlfred Perlstein r = (*rootp)->rlink; /* D1: */ 4964566a3eSAlfred Perlstein if ((q = (*rootp)->llink) == NULL) /* Left NULL? */ 5064566a3eSAlfred Perlstein q = r; 5164566a3eSAlfred Perlstein else if (r != NULL) { /* Right link is NULL? */ 5264566a3eSAlfred Perlstein if (r->llink == NULL) { /* D2: Find successor */ 5364566a3eSAlfred Perlstein r->llink = q; 5464566a3eSAlfred Perlstein q = r; 5564566a3eSAlfred Perlstein } else { /* D3: Find NULL link */ 5664566a3eSAlfred Perlstein for (q = r->llink; q->llink != NULL; q = r->llink) 5764566a3eSAlfred Perlstein r = q; 5864566a3eSAlfred Perlstein r->llink = q->rlink; 5964566a3eSAlfred Perlstein q->llink = (*rootp)->llink; 6064566a3eSAlfred Perlstein q->rlink = (*rootp)->rlink; 6164566a3eSAlfred Perlstein } 6264566a3eSAlfred Perlstein } 6364566a3eSAlfred Perlstein free(*rootp); /* D4: Free node */ 6464566a3eSAlfred Perlstein *rootp = q; /* link parent to new node */ 6564566a3eSAlfred Perlstein return p; 6664566a3eSAlfred Perlstein } 67