#ifndef LINT
#endif
/*%
* tree - balanced binary tree library
*
* vix 05apr94 [removed vixie.h dependencies; cleaned up formatting, names]
* vix 22jan93 [revisited; uses RCS, ANSI, POSIX; has bug fixes]
* vix 23jun86 [added delete uar to add for replaced nodes]
* vix 20jun86 [added tree_delete per wirth a+ds (mod2 v.) p. 224]
* vix 06feb86 [added tree_mung()]
* vix 02feb86 [added tree balancing from wirth "a+ds=p" p. 220-221]
* vix 14dec85 [written]
*/
/*%
* This program text was created by Paul Vixie using examples from the book:
* "Algorithms & Data Structures," Niklaus Wirth, Prentice-Hall, 1986, ISBN
* 0-13-022005-1. Any errors in the conversion from Modula-2 to C are Paul
* Vixie's.
*/
/*
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (c) 1996-1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*#define DEBUG "tree"*/
#include "port_before.h"
#include <stdio.h>
#include <stdlib.h>
#include "port_after.h"
#include <isc/memcluster.h>
#ifdef DEBUG
static int debugDepth = 0;
debugDepth, DEBUG, \
debugFuncs[debugDepth]); \
debugDepth++; \
}
debugDepth--; \
debugDepth, DEBUG, \
debugFuncs[debugDepth]); \
return (value); \
}
# define RETV { \
debugDepth--; \
debugDepth, DEBUG, \
debugFuncs[debugDepth]); \
return; \
}
#else
# define RETV return;
#endif
#ifndef TRUE
# define FALSE 0
#endif
void
ENTER("tree_init")
}
ENTER("tree_srch")
if (*ppr_tree) {
if (i_comp > 0)
p_user))
if (i_comp < 0)
p_user))
/* not higher, not lower... this must be the one.
*/
}
/* grounded. NOT found.
*/
}
{
ENTER("tree_add")
}
int
{
ENTER("tree_delete");
&i_balance, &i_uar_called))
}
int
ENTER("tree_trav")
if (!*ppr_tree)
}
void
ENTER("tree_mung")
if (*ppr_tree) {
if (pfv_uar)
}
}
static tree *
{
int cmp;
ENTER("sprout")
/* are we grounded? if so, add the node "here" and set the rebalance
* flag, then exit.
*/
if (!*ppr) {
MSG("grounded. adding new node, setting h=true")
if (*ppr) {
*pi_balance = TRUE;
}
}
/* compare the data using routine passed by caller.
*/
/* if LESS, prepare to move to the left.
*/
if (cmp < 0) {
MSG("LESS. sprouting left.")
MSG("LESS: left branch has grown")
case 1:
/* right branch WAS longer; bal is ok now */
MSG("LESS: case 1.. bal restored implicitly")
*pi_balance = FALSE;
break;
case 0:
/* balance WAS okay; now left branch longer */
MSG("LESS: case 0.. balnce bad but still ok")
break;
case -1:
/* left branch was already too long. rebal */
MSG("LESS: case -1: rebalancing")
MSG("LESS: single LL")
} else { /*%< double LR */
MSG("LESS: double LR")
else
else
} /*else*/
*pi_balance = FALSE;
} /*switch*/
} /*if*/
} /*if*/
/* if MORE, prepare to move to the right.
*/
if (cmp > 0) {
MSG("MORE: sprouting to the right")
if (sub && *pi_balance) {
MSG("MORE: right branch has grown")
case -1:
MSG("MORE: balance was off, fixed implicitly")
*pi_balance = FALSE;
break;
case 0:
MSG("MORE: balance was okay, now off but ok")
break;
case 1:
MSG("MORE: balance was off, need to rebalance")
MSG("MORE: single RR")
} else { /*%< double RL */
MSG("MORE: double RL")
else
else
} /*else*/
*pi_balance = FALSE;
} /*switch*/
} /*if*/
} /*if*/
/* not less, not more: this is the same key! replace...
*/
MSG("FOUND: Replacing data value")
*pi_balance = FALSE;
if (pfv_delete)
}
static int
{
ENTER("delete")
MSG("key not in tree")
}
if (i_comp > 0) {
MSG("too high - scan left")
if (*pi_balance)
} else if (i_comp < 0) {
MSG("too low - scan right")
if (*pi_balance)
} else {
MSG("equal")
MSG("right subtree null")
*pi_balance = TRUE;
MSG("right subtree non-null, left subtree null")
*pi_balance = TRUE;
} else {
MSG("neither subtree null")
if (*pi_balance)
}
if (!*pi_uar_called && pfv_uar)
/* Thanks to wuth@castrov.cuc.ab.ca for the following stmt. */
}
}
static void
{
ENTER("del")
if (*pi_balance)
} else {
if (pfv_uar)
*pi_uar_called = TRUE;
*pi_balance = TRUE;
}
}
static void
ENTER("bal_L")
MSG("left branch has shrunk")
case -1:
MSG("was imbalanced, fixed implicitly")
break;
case 0:
MSG("was okay, is now one off")
*pi_balance = FALSE;
break;
case 1:
MSG("was already off, this is too much")
if (b1 >= 0) {
MSG("single RR")
if (b1 == 0) {
MSG("b1 == 0")
*pi_balance = FALSE;
} else {
MSG("b1 != 0")
}
} else {
MSG("double RL")
if (b2 == 1)
else
if (b2 == -1)
else
}
}
}
static void
ENTER("bal_R")
MSG("right branch has shrunk")
case 1:
MSG("was imbalanced, fixed implicitly")
break;
case 0:
MSG("was okay, is now one off")
*pi_balance = FALSE;
break;
case -1:
MSG("was already off, this is too much")
if (b1 <= 0) {
MSG("single LL")
if (b1 == 0) {
MSG("b1 == 0")
*pi_balance = FALSE;
} else {
MSG("b1 != 0")
}
} else {
MSG("double LR")
if (b2 == -1)
else
if (b2 == 1)
else
}
}
}
/*! \file */