Backed out changes that attempted to address a pointer array using -1,0,1.
authorChristopher R. Hertel <crh@samba.org>
Wed, 24 Dec 1997 02:50:19 +0000 (02:50 +0000)
committerChristopher R. Hertel <crh@samba.org>
Wed, 24 Dec 1997 02:50:19 +0000 (02:50 +0000)
Jeremy pointed out that there might be problems with this.  Darn shame.
(This used to be commit ce9acc96a6cbc91f0a3f95221c3e8f801cbdb602)

source3/ubiqx/ubi_AVLtree.c
source3/ubiqx/ubi_AVLtree.h
source3/ubiqx/ubi_BinTree.c
source3/ubiqx/ubi_BinTree.h
source3/ubiqx/ubi_SplayTree.c
source3/ubiqx/ubi_SplayTree.h

index a864b160b5532f840dc476867386fced38a14d65..2cd8d1cbedf02390c99601f1755c3329c05ac388 100644 (file)
@@ -9,11 +9,9 @@
  *  This module provides an implementation of AVL height balanced binary
  *  trees.  (Adelson-Velskii, Landis 1962)
  *
- *  This header file contains the basic AVL structure and pointer typedefs
- *  as well as the prototypes needed to access the functions in the AVL
- *  module ubi_AVLtree.  The .c file implements the low-level height balancing
- *  routines that manage the AVL tree, plus all of the basic primops for
- *  adding, searching for, and deleting nodes.
+ *  This file implements the core of the height-balanced (AVL) tree management
+ *  routines.  The header file, ubi_AVLtree.h, contains function prototypes
+ *  for all "exported" functions.
  *
  * -------------------------------------------------------------------------- **
  *
  * -------------------------------------------------------------------------- **
  *
  * Log: ubi_AVLtree.c,v
- * Revision 3.1  1997/12/18 06:26:51  crh
- * Fixed some comment bugs.
+ * Revision 2.5  1997/12/23 04:00:42  crh
+ * In this version, all constants & macros defined in the header file have
+ * the ubi_tr prefix.  Also cleaned up anything that gcc complained about
+ * when run with '-pedantic -fsyntax-only -Wall'.
  *
- * Revision 3.0  1997/12/08 05:38:55  crh
- * This is a new major revision level.  The handling of the pointers in the
- * ubi_trNode structure was redesigned.  The result is that there are fewer
- * macros floating about, and fewer cases in which values have to be
- * incremented or decremented.  See ubi_BinTree for more information.
+ * Revision 2.4  1997/07/26 04:36:20  crh
+ * Andrew Leppard, aka "Grazgur", discovered that I still had my brains tied
+ * on backwards with respect to node deletion.  I did some more digging and
+ * discovered that I was not changing the balance values correctly in the
+ * single rotation functions.  Double rotation was working correctly because
+ * the formula for changing the balance values is the same for insertion or
+ * deletion.  Not so for single rotation.
  *
- * Revision 2; 1995/03/05 - 1997/12/07:
- * An overhaul to the node delete process.  I had gotten it wrong in a
- * couple of places, thought I'd fixed it, and then found that I'd missed
- * something more.  Thanks to Andrew Leppard for the bug report!
+ * I have tested the fix by loading the tree with over 44 thousand names,
+ * deleting 2,629 of them (all those in which the second character is 'u')
+ * and then walking the tree recursively to verify that the balance factor of
+ * each node is correct.  Passed.
  *
- * Revision 1;  93/10/15 - 95/03/05:
- * Added the ubi_tr defines.  See ubi_BinTree.h for more info.
+ * Thanks Andrew!
+ *
+ * Also:
+ * + Changed ubi_TRUE and ubi_FALSE to ubi_trTRUE and ubi_trFALSE.
+ * + Rewrote the ubi_tr<func> macros because they weren't doing what I'd
+ *   hoped they would do (see the bottom of the header file).  They work now.
+ *
+ * Revision 2.3  1997/06/03 04:41:35  crh
+ * Changed TRUE and FALSE to ubi_TRUE and ubi_FALSE to avoid causing
+ * problems.
+ *
+ * Revision 2.2  1995/10/03 22:16:01  CRH
+ * Ubisized!
+ *
+ * Revision 2.1  95/03/09  23:45:59  CRH
+ * Added the ModuleID static string and function.  These modules are now
+ * self-identifying.
+ * 
+ * Revision 2.0  95/03/05  14:10:51  CRH
+ * This revision of ubi_AVLtree coincides with revision 2.0 of ubi_BinTree,
+ * and so includes all of the changes to that module.  In addition, a bug in
+ * the node deletion process has been fixed.
+ *
+ * After rewriting the Locate() function in ubi_BinTree, I decided that it was
+ * time to overhaul this module.  In the process, I discovered a bug related
+ * to node deletion.  To fix the bug, I wrote function Debalance().  A quick
+ * glance will show that it is very similar to the Rebalance() function.  In
+ * previous versions of this module, I tried to include the functionality of
+ * Debalance() within Rebalance(), with poor results.
+ *
+ * Revision 1.0  93/10/15  22:58:56  CRH
+ * With this revision, I have added a set of #define's that provide a single,
+ * standard API to all existing tree modules.  Until now, each of the three
+ * existing modules had a different function and typedef prefix, as follows:
+ *
+ *       Module        Prefix
+ *     ubi_BinTree     ubi_bt
+ *     ubi_AVLtree     ubi_avl
+ *     ubi_SplayTree   ubi_spt
+ *
+ * To further complicate matters, only those portions of the base module
+ * (ubi_BinTree) that were superceeded in the new module had the new names.
+ * For example, if you were using ubi_AVLtree, the AVL node structure was
+ * named "ubi_avlNode", but the root structure was still "ubi_btRoot".  Using
+ * SplayTree, the locate function was called "ubi_sptLocate", but the next
+ * and previous functions remained "ubi_btNext" and "ubi_btPrev".
+ *
+ * This was not too terrible if you were familiar with the modules and knew
+ * exactly which tree model you wanted to use.  If you wanted to be able to
+ * change modules (for speed comparisons, etc), things could get messy very
+ * quickly.
+ *
+ * So, I have added a set of defined names that get redefined in any of the
+ * descendant modules.  To use this standardized interface in your code,
+ * simply replace all occurances of "ubi_bt", "ubi_avl", and "ubi_spt" with
+ * "ubi_tr".  The "ubi_tr" names will resolve to the correct function or
+ * datatype names for the module that you are using.  Just remember to
+ * include the header for that module in your program file.  Because these
+ * names are handled by the preprocessor, there is no added run-time
+ * overhead.
+ *
+ * Note that the original names do still exist, and can be used if you wish
+ * to write code directly to a specific module.  This should probably only be
+ * done if you are planning to implement a new descendant type, such as
+ * red/black trees.  CRH
  *
  *  V0.0 - May, 1990   -  Written by Christopher R. Hertel (CRH).
  *
  */
 
 static char ModuleID[] = "ubi_AVLtree\n\
-\tRevision: 3.1\n\
-\tDate: 1997/12/18 06:26:51 GMT\n\
+\tRevision: 2.5\n\
+\tDate: 1997/12/23 04:00:42\n\
 \tAuthor: crh\n";
 
 /* ========================================================================== **
@@ -101,7 +166,7 @@ static ubi_avlNodePtr L1( ubi_avlNodePtr p )
   tmp->Link[ubi_trPARENT]  = p->Link[ubi_trPARENT];
   tmp->gender              = p->gender;
   if(tmp->Link[ubi_trPARENT])
-    (tmp->Link[ubi_trPARENT])->Link[(tmp->gender)] = tmp;
+    (tmp->Link[ubi_trPARENT])->Link[(int)(tmp->gender)] = tmp;
   p->Link[ubi_trPARENT]    = tmp;
   p->gender                = ubi_trLEFT;
   if( p->Link[ubi_trRIGHT] )
@@ -109,7 +174,7 @@ static ubi_avlNodePtr L1( ubi_avlNodePtr p )
     p->Link[ubi_trRIGHT]->Link[ubi_trPARENT] = p;
     (p->Link[ubi_trRIGHT])->gender           = ubi_trRIGHT;
     }
-  p->balance -= tmp->balance;
+  p->balance -= ubi_trNormalize( tmp->balance );
   (tmp->balance)--;
   return( tmp );
   } /* L1 */
@@ -133,7 +198,7 @@ static ubi_avlNodePtr R1( ubi_avlNodePtr p )
   tmp->Link[ubi_trPARENT]  = p->Link[ubi_trPARENT];
   tmp->gender              = p->gender;
   if(tmp->Link[ubi_trPARENT])
-    (tmp->Link[ubi_trPARENT])->Link[(tmp->gender)] = tmp;
+    (tmp->Link[ubi_trPARENT])->Link[(int)(tmp->gender)] = tmp;
   p->Link[ubi_trPARENT]    = tmp;
   p->gender                = ubi_trRIGHT;
   if(p->Link[ubi_trLEFT])
@@ -141,7 +206,7 @@ static ubi_avlNodePtr R1( ubi_avlNodePtr p )
     p->Link[ubi_trLEFT]->Link[ubi_trPARENT]  = p;
     p->Link[ubi_trLEFT]->gender              = ubi_trLEFT;
     }
-  p->balance -= tmp->balance;
+  p->balance -= ubi_trNormalize( tmp->balance );
   (tmp->balance)++;
   return( tmp );
   } /* R1 */
@@ -183,7 +248,7 @@ static ubi_avlNodePtr L2( ubi_avlNodePtr tree )
     tmp->Link[ubi_trLEFT]->gender               = ubi_trLEFT;
     }
   if(newroot->Link[ubi_trPARENT])
-    newroot->Link[ubi_trPARENT]->Link[newroot->gender] = newroot;
+    newroot->Link[ubi_trPARENT]->Link[(int)(newroot->gender)] = newroot;
 
   switch( newroot->balance )
     {
@@ -235,7 +300,7 @@ static ubi_avlNodePtr R2( ubi_avlNodePtr tree )
     tmp->Link[ubi_trRIGHT]->gender              = ubi_trRIGHT;
     }
   if(newroot->Link[ubi_trPARENT])
-    newroot->Link[ubi_trPARENT]->Link[newroot->gender] = newroot;
+    newroot->Link[ubi_trPARENT]->Link[(int)(newroot->gender)] = newroot;
 
   switch( newroot->balance )
     {
@@ -251,7 +316,7 @@ static ubi_avlNodePtr R2( ubi_avlNodePtr tree )
   } /* R2 */
 
 
-static ubi_avlNodePtr Adjust( ubi_avlNodePtr p, signed char LorR )
+static ubi_avlNodePtr Adjust( ubi_avlNodePtr p, char LorR )
   /* ------------------------------------------------------------------------ **
    * Adjust the balance value at node *p.  If necessary, rotate the subtree
    * rooted at p.
@@ -270,12 +335,12 @@ static ubi_avlNodePtr Adjust( ubi_avlNodePtr p, signed char LorR )
    */
   {
   if( p->balance != LorR )
-    p->balance += LorR;
+    p->balance += ubi_trNormalize(LorR);
   else
     {
-    signed char tallerbal;  /* Balance of root of the taller subtree of p. */
+    char tallerbal;  /* Balance value of the root of the taller subtree of p. */
 
-    tallerbal = p->Link[LorR]->balance;
+    tallerbal = p->Link[(int)LorR]->balance;
     if( ( ubi_trEQUAL == tallerbal ) || ( p->balance == tallerbal ) )
       p = ( (ubi_trLEFT==LorR) ? R1(p) : L1(p) );   /* single rotation */
     else
@@ -286,7 +351,7 @@ static ubi_avlNodePtr Adjust( ubi_avlNodePtr p, signed char LorR )
 
 static ubi_avlNodePtr Rebalance( ubi_avlNodePtr Root,
                                  ubi_avlNodePtr subtree,
-                                 signed char    LorR )
+                                 char           LorR )
   /* ------------------------------------------------------------------------ **
    * Rebalance the tree following an insertion.
    *
@@ -324,7 +389,7 @@ static ubi_avlNodePtr Rebalance( ubi_avlNodePtr Root,
 
 static ubi_avlNodePtr Debalance( ubi_avlNodePtr Root,
                                  ubi_avlNodePtr subtree,
-                                 signed char    LorR )
+                                 char           LorR )
   /* ------------------------------------------------------------------------ **
    * Rebalance the tree following a deletion.
    *
@@ -431,19 +496,19 @@ static void SwapNodes( ubi_btRootPtr  RootPtr,
   ubi_avlNodePtr  dummy_p = &dummy;
 
   if( Node1->Link[ubi_trPARENT] )
-    Parent = &((Node1->Link[ubi_trPARENT])->Link[Node1->gender]);
+    Parent = &((Node1->Link[ubi_trPARENT])->Link[(int)(Node1->gender)]);
   else
     Parent = (ubi_avlNodePtr *)&(RootPtr->root);
   ReplaceNode( Parent, Node1, dummy_p );
 
   if( Node2->Link[ubi_trPARENT] )
-    Parent = &((Node2->Link[ubi_trPARENT])->Link[Node2->gender]);
+    Parent = &((Node2->Link[ubi_trPARENT])->Link[(int)(Node2->gender)]);
   else
     Parent = (ubi_avlNodePtr *)&(RootPtr->root);
   ReplaceNode( Parent, Node2, Node1 );
 
   if( dummy_p->Link[ubi_trPARENT] )
-    Parent = &((dummy_p->Link[ubi_trPARENT])->Link[dummy_p->gender]);
+    Parent = &((dummy_p->Link[ubi_trPARENT])->Link[(int)(dummy_p->gender)]);
   else
     Parent = (ubi_avlNodePtr *)&(RootPtr->root);
   ReplaceNode( Parent, dummy_p, Node2 );
@@ -575,7 +640,7 @@ ubi_avlNodePtr ubi_avlRemove( ubi_btRootPtr  RootPtr,
    */
   if( DeadNode->Link[ubi_trPARENT] )
     parentp = (ubi_btNodePtr *)
-              &((DeadNode->Link[ubi_trPARENT])->Link[(DeadNode->gender)]);
+              &((DeadNode->Link[ubi_trPARENT])->Link[(int)(DeadNode->gender)]);
   else
     parentp = &( RootPtr->root );
 
@@ -586,9 +651,9 @@ ubi_avlNodePtr ubi_avlRemove( ubi_btRootPtr  RootPtr,
     (*parentp) = NULL;
   else
     {
-    p = (ubi_btNodePtr)(DeadNode->Link[(DeadNode->balance)]);
-    p->Link[ubi_trPARENT]  = (ubi_btNodePtr)DeadNode->Link[ubi_trPARENT];
-    p->gender              = DeadNode->gender;
+    p = (ubi_btNodePtr)(DeadNode->Link[(int)(DeadNode->balance)]);
+    p->Link[ubi_trPARENT] = (ubi_btNodePtr)DeadNode->Link[ubi_trPARENT];
+    p->gender  = DeadNode->gender;
     (*parentp) = p;
     }
   RootPtr->root = (ubi_btNodePtr)Debalance( (ubi_avlNodePtr)RootPtr->root,
index c7cac0ed1e53f8e247e7b569a2393767904aafb9..ebae7f3c1316e53a3aae716741badd3c5149a82c 100644 (file)
  *
  * -------------------------------------------------------------------------- **
  * Log: ubi_AVLtree.h,v
- * Revision 3.1  1997/12/18 06:27:01  crh
- * Fixed some comment bugs.
+ * Revision 2.5  1997/12/23 04:00:15  crh
+ * In this version, all constants & macros defined in the header file have
+ * the ubi_tr prefix.  Also cleaned up anything that gcc complained about
+ * when run with '-pedantic -fsyntax-only -Wall'.
  *
- * Revision 3.0  1997/12/08 05:39:01  crh
- * This is a new major revision level.  The handling of the pointers in the
- * ubi_trNode structure was redesigned.  The result is that there are fewer
- * macros floating about, and fewer cases in which values have to be
- * incremented or decremented.  See ubi_BinTree for more information.
+ * Revision 2.4  1997/07/26 04:36:23  crh
+ * Andrew Leppard, aka "Grazgur", discovered that I still had my brains tied
+ * on backwards with respect to node deletion.  I did some more digging and
+ * discovered that I was not changing the balance values correctly in the
+ * single rotation functions.  Double rotation was working correctly because
+ * the formula for changing the balance values is the same for insertion or
+ * deletion.  Not so for single rotation.
  *
- * Revision 2; 1995/03/05 - 1997/12/07:
- * An overhaul to the node delete process.  I had gotten it wrong in a
- * couple of places, thought I'd fixed it, and then found that I'd missed
- * something more.  Thanks to Andrew Leppard for the bug report!
+ * I have tested the fix by loading the tree with over 44 thousand names,
+ * deleting 2,629 of them (all those in which the second character is 'u')
+ * and then walking the tree recursively to verify that the balance factor of
+ * each node is correct.  Passed.
+ *
+ * Thanks Andrew!
+ *
+ * Also:
+ * + Changed ubi_TRUE and ubi_FALSE to ubi_trTRUE and ubi_trFALSE.
+ * + Rewrote the ubi_tr<func> macros because they weren't doing what I'd
+ *   hoped they would do (see the bottom of the header file).  They work now.
+ *
+ * Revision 2.3  1997/06/03 05:22:07  crh
+ * Changed TRUE and FALSE to ubi_TRUE and ubi_FALSE to avoid causing
+ * problems.
+ *
+ * Revision 2.2  1995/10/03 22:15:47  CRH
+ * Ubisized!
+ *
+ * Revision 2.1  95/03/09  23:46:44  CRH
+ * Added the ModuleID static string and function.  These modules are now
+ * self-identifying.
  * 
- * Revision 1;  93/10/15 - 95/03/05:
- * Added the ubi_tr defines.  See ubi_BinTree.h for more info.
+ * Revision 2.0  95/03/05  14:11:22  CRH
+ * This revision of ubi_AVLtree coincides with revision 2.0 of ubi_BinTree,
+ * and so includes all of the changes to that module.  In addition, a bug in
+ * the node deletion process has been fixed.
+ *
+ * After rewriting the Locate() function in ubi_BinTree, I decided that it was
+ * time to overhaul this module.  In the process, I discovered a bug related
+ * to node deletion.  To fix the bug, I wrote function Debalance().  A quick
+ * glance will show that it is very similar to the Rebalance() function.  In
+ * previous versions of this module, I tried to include the functionality of
+ * Debalance() within Rebalance(), with poor results.
+ *
+ * Revision 1.0  93/10/15  22:58:48  CRH
+ * With this revision, I have added a set of #define's that provide a single,
+ * standard API to all existing tree modules.  Until now, each of the three
+ * existing modules had a different function and typedef prefix, as follows:
+ *
+ *       Module        Prefix
+ *     ubi_BinTree     ubi_bt
+ *     ubi_AVLtree     ubi_avl
+ *     ubi_SplayTree   ubi_spt
+ *
+ * To further complicate matters, only those portions of the base module
+ * (ubi_BinTree) that were superceeded in the new module had the new names.
+ * For example, if you were using ubi_AVLtree, the AVL node structure was
+ * named "ubi_avlNode", but the root structure was still "ubi_btRoot".  Using
+ * SplayTree, the locate function was called "ubi_sptLocate", but the next
+ * and previous functions remained "ubi_btNext" and "ubi_btPrev".
+ *
+ * This was not too terrible if you were familiar with the modules and knew
+ * exactly which tree model you wanted to use.  If you wanted to be able to
+ * change modules (for speed comparisons, etc), things could get messy very
+ * quickly.
+ *
+ * So, I have added a set of defined names that get redefined in any of the
+ * descendant modules.  To use this standardized interface in your code,
+ * simply replace all occurances of "ubi_bt", "ubi_avl", and "ubi_spt" with
+ * "ubi_tr".  The "ubi_tr" names will resolve to the correct function or
+ * datatype names for the module that you are using.  Just remember to
+ * include the header for that module in your program file.  Because these
+ * names are handled by the preprocessor, there is no added run-time
+ * overhead.
+ *
+ * Note that the original names do still exist, and can be used if you wish
+ * to write code directly to a specific module.  This should probably only be
+ * done if you are planning to implement a new descendant type, such as
+ * red/black trees.  CRH
  *
  *  V0.0 - May, 1990   -  Written by Christopher R. Hertel (CRH).
  *
  *       header so that you can use the structure as a building block.
  *
  *  The fields are as follows:
- *    leftlink -  A space filler.  This field will be accessed as Link[-1].
  *    Link     -  An array of pointers.  These pointers are manipulated by the
  *                BT and AVL routines, and indicate the left and right child
  *                nodes, plus the parent node.  By keeping track of the parent
  *                indicates which subtree of the current node is longer, or if
  *                the subtrees are, in fact, balanced with respect to each
  *                other.
- *
+ *  ------------------------------------------------------------------------- **
  */
 
-typedef struct ubi_avlNodeStruct
-  {
-  struct ubi_avlNodeStruct *leftlink;
-  struct ubi_avlNodeStruct *Link[2];
-  signed char               gender; 
-  signed char               balance;
-  } ubi_avlNode;
+typedef struct ubi_avlNodeStruct {
+  struct ubi_avlNodeStruct
+         *Link[3];      /* Normal Binary Tree Node type.                      */
+  char    gender;       /* The node is either the RIGHT or LEFT child of its  */
+                        /* parent, or is the root node.                       */
+  char    balance;      /* In an AVL tree, each node is the root of a subtree */
+                        /* that may be balanced, or be one node longer to the */
+                        /* right or left.  This field keeps track of the      */
+                        /* balance value of each node.                        */
+    } ubi_avlNode;
 
-typedef ubi_avlNode *ubi_avlNodePtr;    /* a Pointer to an AVL node. */
+typedef ubi_avlNode *ubi_avlNodePtr;    /* a Pointer to an AVL node */
 
 /* -------------------------------------------------------------------------- **
- *  Function prototypes...
+ *  Function prototypes.
+ * -------------------------------------------------------------------------- **
  */
 
 ubi_avlNodePtr ubi_avlInitNode( ubi_avlNodePtr NodePtr );
index 15bdeb1d859c61888487298451a1129de8d66ed2..501f3eeca79812c435f86cdf03e7f73e7a8b4e6a 100644 (file)
@@ -6,7 +6,7 @@
  *  Email:  crh@ubiqx.mn.org
  * -------------------------------------------------------------------------- **
  *
- *  This module implements simple binary trees.
+ *  This module implements a simple binary tree.
  *
  * -------------------------------------------------------------------------- **
  *
  * -------------------------------------------------------------------------- **
  *
  * Log: ubi_BinTree.c,v
- * Revision 3.0  1997/12/08 06:49:11  crh
- * This is a new major revision level for all ubiqx binary tree modules.
- * In previous releases, the ubi_trNode structure looked like this:
+ * Revision 2.5  1997/12/23 03:56:29  crh
+ * In this version, all constants & macros defined in the header file have
+ * the ubi_tr prefix.  Also cleaned up anything that gcc complained about
+ * when run with '-pedantic -fsyntax-only -Wall'.
  *
- *   typedef struct ubi_btNodeStruct
- *     {
- *     struct ubi_btNodeStruct *Link[3];
- *     signed char              gender;
- *     } ubi_btNode;
+ * Revision 2.4  1997/07/26 04:11:10  crh
+ * + Just to be annoying I changed ubi_TRUE and ubi_FALSE to ubi_trTRUE
+ *   and ubi_trFALSE.
+ * + There is now a type ubi_trBool to go with ubi_trTRUE and ubi_trFALSE.
+ * + There used to be something called "ubi_TypeDefs.h".  I got rid of it.
+ * + Added function ubi_btLeafNode().
  *
- * As a result, the pointers were indexed as
+ * Revision 2.3  1997/06/03 05:16:17  crh
+ * Changed TRUE and FALSE to ubi_TRUE and ubi_FALSE to avoid conflicts.
+ * Also changed the interface to function InitTree().  See the comments
+ * for this function for more information.
  *
- *   Link[0] == Left Child
- *   Link[1] == Parent
- *   Link[2] == Right Child
+ * Revision 2.2  1995/10/03 22:00:07  CRH
+ * Ubisized!
+ * 
+ * Revision 2.1  95/03/09  23:37:10  CRH
+ * Added the ModuleID static string and function.  These modules are now
+ * self-identifying.
+ * 
+ * Revision 2.0  95/02/27  22:00:17  CRH
+ * Revision 2.0 of this program includes the following changes:
  *
- * With this release, the node structure changes to:
+ *     1)  A fix to a major typo in the RepaceNode() function.
+ *     2)  The addition of the static function Border().
+ *     3)  The addition of the public functions FirstOf() and LastOf(), which
+ *         use Border(). These functions are used with trees that allow
+ *         duplicate keys.
+ *     4)  A complete rewrite of the Locate() function.  Locate() now accepts
+ *         a "comparison" operator.
+ *     5)  Overall enhancements to both code and comments.
  *
- *   typedef struct ubi_btNodeStruct
- *     {
- *     struct ubi_btNodeStruct *leftlink
- *     struct ubi_btNodeStruct *Link[2];
- *     signed char              gender;
- *     } ubi_btNode;
+ * I decided to give this a new major rev number because the interface has
+ * changed.  In particular, there are two new functions, and changes to the
+ * Locate() function.
  *
- * The leftlink field is used as a place holder, and the pointers are now
- * index as
- *
- *   Link[-1] == Left Child  (aka. leftlink)
- *   Link[ 0] == Parent
- *   Link[ 1] == Right Child
- *
- * which is much nicer.  Doing things this way removes the need to shift
- * values between the two numbering schemes, thus removing one macro,
- * simplifying another, and getting rid of a whole bunch of increment &
- * decrement operations.
- *
- * Revision 2; 1995/02/27 - 1997/12/07 included:
- *  - The addition of the ModuleID static string and ubi_ModuleID() function.
- *  - The addition of the public functions FirstOf() and LastOf(). These
- *    functions are used with trees that allow duplicate keys.
- *  - The addition of the ubi_btLeafNode() function.
- *  - A rewrite of the Locate() function.
- *  - A change to the parameter list in function ubi_btInitTree().
- *  - Bugfixes.
- *
- * Revision 1; 93/10/15 - 95/02/27:
- * Revision 1 introduced a set of #define's that provide a single API to all
- * of the existing tree modules.  Each of these modules has a different name
- * prefix, as follows:
+ * Revision 1.0  93/10/15  22:44:59  CRH
+ * With this revision, I have added a set of #define's that provide a single,
+ * standard API to all existing tree modules.  Until now, each of the three
+ * existing modules had a different function and typedef prefix, as follows:
  *
  *       Module        Prefix
  *     ubi_BinTree     ubi_bt
  *     ubi_AVLtree     ubi_avl
  *     ubi_SplayTree   ubi_spt
  *
- * Only those portions of the base module (ubi_BinTree) that are superceeded
- * in the descendant module have new names.  For example, the AVL node
- * structure in ubi_AVLtree.h is named "ubi_avlNode", but the root structure
- * is still "ubi_btRoot".  Using SplayTree, the locate function is called
- * "ubi_sptLocate", but the next and previous functions remained "ubi_btNext"
- * and "ubi_btPrev".
+ * To further complicate matters, only those portions of the base module
+ * (ubi_BinTree) that were superceeded in the new module had the new names.
+ * For example, if you were using ubi_AVLtree, the AVL node structure was
+ * named "ubi_avlNode", but the root structure was still "ubi_btRoot".  Using
+ * SplayTree, the locate function was called "ubi_sptLocate", but the next
+ * and previous functions remained "ubi_btNext" and "ubi_btPrev".
  *
- * This is confusing.
+ * This was not too terrible if you were familiar with the modules and knew
+ * exactly which tree model you wanted to use.  If you wanted to be able to
+ * change modules (for speed comparisons, etc), things could get messy very
+ * quickly.
  *
- * So, I added a set of defined names that get redefined in any of the
+ * So, I have added a set of defined names that get redefined in any of the
  * descendant modules.  To use this standardized interface in your code,
  * simply replace all occurances of "ubi_bt", "ubi_avl", and "ubi_spt" with
  * "ubi_tr".  The "ubi_tr" names will resolve to the correct function or
  * Note that the original names do still exist, and can be used if you wish
  * to write code directly to a specific module.  This should probably only be
  * done if you are planning to implement a new descendant type, such as
- * red/black trees, or if you plan to use two or more specific tree types
- * in the same piece of code.  CRH
+ * red/black trees.  CRH
  *
  *  V0.0 - June, 1991   -  Written by Christopher R. Hertel (CRH).
  *
  */
 
 static char ModuleID[] = "ubi_BinTree\n\
-\tRevision: 3.0\n\
-\tDate: 1997/12/08 06:49:11\n\
+\tRevision: 2.5\n\
+\tDate: 1997/12/23 03:56:29\n\
 \tAuthor: crh\n";
 
 /* ========================================================================== **
@@ -134,7 +130,7 @@ static ubi_btNodePtr qFind( ubi_btCompFunc cmp,
   /* ------------------------------------------------------------------------ **
    * This function performs a non-recursive search of a tree for a node
    * matching a specific key.  It is called "qFind()" because it is
-   * (probably a little bit) faster that TreeFind (below).
+   * faster that TreeFind (below).
    *
    *  Input:
    *     cmp      -  a pointer to the tree's comparison function.
@@ -153,9 +149,9 @@ static ubi_btNodePtr qFind( ubi_btCompFunc cmp,
    * ------------------------------------------------------------------------ **
    */
   {
-  signed char tmp;
+  int tmp;
 
-  while( p && (( tmp = ubi_trNormalize((*cmp)(FindMe, p)) ) != ubi_trEQUAL) )
+  while( p && (( tmp = ubi_trAbNormal((*cmp)(FindMe, p)) ) != ubi_trEQUAL) )
     p = p->Link[tmp];
 
   return( p );
@@ -164,7 +160,7 @@ static ubi_btNodePtr qFind( ubi_btCompFunc cmp,
 static ubi_btNodePtr TreeFind( ubi_btItemPtr  findme,
                                ubi_btNodePtr  p,
                                ubi_btNodePtr *parentp,
-                               signed char   *gender,
+                               char          *gender,
                                ubi_btCompFunc CmpFunc )
   /* ------------------------------------------------------------------------ **
    * TreeFind() searches a tree for a given value (findme).  It will return a
@@ -195,16 +191,15 @@ static ubi_btNodePtr TreeFind( ubi_btItemPtr  findme,
   {
   register ubi_btNodePtr tmp_p = p;
   ubi_btNodePtr tmp_pp         = NULL;
-  signed char   tmp_gender     = ubi_trEQUAL;
-  signed char   tmp_cmp;
+  int tmp_gender               = ubi_trEQUAL;
+  int tmp_cmp;
 
   while( tmp_p
-      && (ubi_trEQUAL != (tmp_cmp = ubi_trNormalize((*CmpFunc)(findme, tmp_p))))
-       )
+     && (ubi_trEQUAL != (tmp_cmp = ubi_trAbNormal((*CmpFunc)(findme, tmp_p)))) )
     {
-    tmp_pp  = tmp_p;                /* Keep track of previous node. */
-    tmp_gender = tmp_cmp;           /* Keep track of sex of child.  */
-    tmp_p = tmp_p->Link[tmp_cmp];   /* Go to child. */
+    tmp_pp     = tmp_p;                 /* Keep track of previous node. */
+    tmp_gender = tmp_cmp;               /* Keep track of sex of child.  */
+    tmp_p      = tmp_p->Link[tmp_cmp];  /* Go to child. */
     }
   *parentp = tmp_pp;                /* Return results. */
   *gender  = tmp_gender;
@@ -214,7 +209,7 @@ static ubi_btNodePtr TreeFind( ubi_btItemPtr  findme,
 static void ReplaceNode( ubi_btNodePtr *parent,
                          ubi_btNodePtr  oldnode,
                          ubi_btNodePtr  newnode )
-  /* ------------------------------------------------------------------------ **
+  /* ------------------------------------------------------------------ *
    * Remove node oldnode from the tree, replacing it with node newnode.
    *
    * Input:
@@ -227,8 +222,12 @@ static void ReplaceNode( ubi_btNodePtr *parent,
    *             place of <*oldnode>.
    *
    * Notes:    Don't forget to free oldnode.
-   *
-   * ------------------------------------------------------------------------ **
+   *           Also, this function used to have a really nasty typo
+   *           bug.  "oldnode" and "newnode" were swapped in the line
+   *           that now reads:
+   *     ((unsigned char *)newnode)[i] = ((unsigned char *)oldnode)[i];
+   *           Bleah!
+   * ------------------------------------------------------------------ *
    */
   {
   register int i;
@@ -236,17 +235,12 @@ static void ReplaceNode( ubi_btNodePtr *parent,
 
   for( i = 0; i < btNodeSize; i++ ) /* Copy node internals to new node. */
     ((unsigned char *)newnode)[i] = ((unsigned char *)oldnode)[i];
-
-  /* Old node's parent points to new child. */
-  (*parent) = newnode;
-
+  (*parent) = newnode;              /* Old node's parent points to new child. */
   /* Now tell the children about their new step-parent. */
-  if( oldnode->Link[ubi_trLEFT ] )
-    (oldnode->Link[ubi_trLEFT ])->Link[ubi_trPARENT] = newnode;
-
+  if( oldnode->Link[ubi_trLEFT] )
+    (oldnode->Link[ubi_trLEFT])->Link[ubi_trPARENT] = newnode;
   if( oldnode->Link[ubi_trRIGHT] )
     (oldnode->Link[ubi_trRIGHT])->Link[ubi_trPARENT] = newnode;
-
   } /* ReplaceNode */
 
 static void SwapNodes( ubi_btRootPtr RootPtr,
@@ -274,21 +268,21 @@ static void SwapNodes( ubi_btRootPtr RootPtr,
 
   /* Replace Node 1 with the dummy, thus removing Node1 from the tree. */
   if( Node1->Link[ubi_trPARENT] )
-    Parent = &((Node1->Link[ubi_trPARENT])->Link[Node1->gender]);
+    Parent = &((Node1->Link[ubi_trPARENT])->Link[(int)(Node1->gender)]);
   else
     Parent = &(RootPtr->root);
   ReplaceNode( Parent, Node1, dummy_p );
 
   /* Swap Node 1 with Node 2, placing Node 1 back into the tree. */
   if( Node2->Link[ubi_trPARENT] )
-    Parent = &((Node2->Link[ubi_trPARENT])->Link[Node2->gender]);
+    Parent = &((Node2->Link[ubi_trPARENT])->Link[(int)(Node2->gender)]);
   else
     Parent = &(RootPtr->root);
   ReplaceNode( Parent, Node2, Node1 );
 
   /* Swap Node 2 and the dummy, thus placing Node 2 back into the tree. */
   if( dummy_p->Link[ubi_trPARENT] )
-    Parent = &((dummy_p->Link[ubi_trPARENT])->Link[dummy_p->gender]);
+    Parent = &((dummy_p->Link[ubi_trPARENT])->Link[(int)(dummy_p->gender)]);
   else
     Parent = &(RootPtr->root);
   ReplaceNode( Parent, dummy_p, Node2 );
@@ -299,7 +293,7 @@ static void SwapNodes( ubi_btRootPtr RootPtr,
  */
 
 static ubi_btNodePtr SubSlide( register ubi_btNodePtr P,
-                               register signed char   whichway )
+                               register int           whichway )
   /* ------------------------------------------------------------------------ **
    * Slide down the side of a subtree.
    *
@@ -327,7 +321,7 @@ static ubi_btNodePtr SubSlide( register ubi_btNodePtr P,
   } /* SubSlide */
 
 static ubi_btNodePtr Neighbor( register ubi_btNodePtr P,
-                               register signed char   whichway )
+                               register int           whichway )
   /* ------------------------------------------------------------------------ **
    * Given starting point p, return the (key order) next or preceeding node
    * in the tree.
@@ -346,7 +340,7 @@ static ubi_btNodePtr Neighbor( register ubi_btNodePtr P,
   if( P )
     {
     if( P->Link[ whichway ] )
-      return( SubSlide( P->Link[ whichway ], ubi_trRevWay(whichway) ) );
+      return( SubSlide( P->Link[ whichway ], (char)ubi_trRevWay(whichway) ) );
     else
       while( P->Link[ ubi_trPARENT ] )
         {
@@ -362,7 +356,7 @@ static ubi_btNodePtr Neighbor( register ubi_btNodePtr P,
 static ubi_btNodePtr Border( ubi_btRootPtr RootPtr,
                              ubi_btItemPtr FindMe,
                              ubi_btNodePtr p,
-                             signed char   whichway )
+                             int           whichway )
   /* ------------------------------------------------------------------------ **
    * Given starting point p, which has a key value equal to *FindMe, locate
    * the first (index order) node with the same key value.
@@ -401,7 +395,7 @@ static ubi_btNodePtr Border( ubi_btRootPtr RootPtr,
    * subtree that contains all of the matching nodes.
    */
   q = p->Link[ubi_trPARENT];
-  while( q && (ubi_trEQUAL == ubi_trNormalize( (*(RootPtr->cmp))(FindMe, q) )) )
+  while( q && (ubi_trEQUAL == ubi_trAbNormal( (*(RootPtr->cmp))(FindMe, q) )) )
     {
     p = q;
     q = p->Link[ubi_trPARENT];
@@ -411,7 +405,8 @@ static ubi_btNodePtr Border( ubi_btRootPtr RootPtr,
   q = p->Link[whichway];
   while( q )
     {
-    if( q = qFind( RootPtr->cmp, FindMe, q ) )
+    q = qFind( RootPtr->cmp, FindMe, q );
+    if( q )
       {
       p = q;
       q = p->Link[whichway];
@@ -431,15 +426,15 @@ long ubi_btSgn( register long x )
    *
    *  Input:  x - a signed long integer value.
    *
-   *  Output: -1, 0, or 1 representing the "sign" of x as follows:
+   *  Output: the "sign" of x, represented as follows:
    *            -1 == negative
    *             0 == zero (no sign)
    *             1 == positive
    *
-   * Note:    This utility is provided in order to facilitate the conversion
-   *          of C comparison function return values into BinTree direction
-   *          values: {ubi_trLEFT, ubi_trPARENT, ubi_trEQUAL}.  It is
-   *          incorporated into the ubi_trNormalize() conversion macro.
+   * Note: This utility is provided in order to facilitate the conversion
+   *       of C comparison function return values into BinTree direction
+   *       values: {LEFT, PARENT, EQUAL}.  It is INCORPORATED into the
+   *       ubi_trAbNormal() conversion macro!
    *
    * ------------------------------------------------------------------------ **
    */
@@ -553,7 +548,7 @@ ubi_trBool ubi_btInsert( ubi_btRootPtr  RootPtr,
   {
   ubi_btNodePtr OtherP,
                 parent = NULL;
-  signed char   tmp;
+  char          tmp;
 
   if( !(OldNode) )       /* If they didn't give us a pointer, supply our own. */
     OldNode = &OtherP;
@@ -570,7 +565,7 @@ ubi_trBool ubi_btInsert( ubi_btRootPtr  RootPtr,
       RootPtr->root = NewNode;
     else
       {
-      parent->Link[tmp]           = NewNode;
+      parent->Link[(int)tmp]      = NewNode;
       NewNode->Link[ubi_trPARENT] = parent;
       NewNode->gender             = tmp;
       }
@@ -593,11 +588,11 @@ ubi_trBool ubi_btInsert( ubi_btRootPtr  RootPtr,
       parent = q;
       if( tmp == ubi_trEQUAL )
         tmp = ubi_trRIGHT;
-      q = q->Link[tmp];
+      q = q->Link[(int)tmp];
       if ( q )
-        tmp = ubi_trNormalize( (*(RootPtr->cmp))(ItemPtr, q) );
+        tmp = ubi_trAbNormal( (*(RootPtr->cmp))(ItemPtr, q) );
       }
-    parent->Link[tmp]            = NewNode;
+    parent->Link[(int)tmp]       = NewNode;
     NewNode->Link[ubi_trPARENT]  = parent;
     NewNode->gender              = tmp;
     (RootPtr->count)++;
@@ -613,7 +608,8 @@ ubi_trBool ubi_btInsert( ubi_btRootPtr  RootPtr,
     if (!(parent))
       ReplaceNode( &(RootPtr->root), *OldNode, NewNode );
     else
-      ReplaceNode( &(parent->Link[(*OldNode)->gender]), *OldNode, NewNode );
+      ReplaceNode( &(parent->Link[(int)((*OldNode)->gender)]),
+                   *OldNode, NewNode );
     return( ubi_trTRUE );
     }
 
@@ -639,7 +635,7 @@ ubi_btNodePtr ubi_btRemove( ubi_btRootPtr RootPtr,
   {
   ubi_btNodePtr p,
                *parentp;
-  signed char   tmp;
+  int           tmp;
 
   /* if the node has both left and right subtrees, then we have to swap
    * it with another node.  The other node we choose will be the Prev()ious
@@ -653,18 +649,18 @@ ubi_btNodePtr ubi_btRemove( ubi_btRootPtr RootPtr,
    * a pointer to the parent pointer, whatever it is.
    */
   if (DeadNode->Link[ubi_trPARENT])
-    parentp = &((DeadNode->Link[ubi_trPARENT])->Link[DeadNode->gender]);
+    parentp = &((DeadNode->Link[ubi_trPARENT])->Link[(int)(DeadNode->gender)]);
   else
     parentp = &( RootPtr->root );
 
   /* Now link the parent to the only grand-child and patch up the gender. */
-  tmp = ((DeadNode->Link[ubi_trLEFT]) ? ubi_trLEFT : ubi_trRIGHT);
+  tmp = ((DeadNode->Link[ubi_trLEFT])?ubi_trLEFT:ubi_trRIGHT);
 
   p = (DeadNode->Link[tmp]);
   if( p )
     {
     p->Link[ubi_trPARENT] = DeadNode->Link[ubi_trPARENT];
-    p->gender             = DeadNode->gender;
+    p->gender       = DeadNode->gender;
     }
   (*parentp) = p;
 
@@ -727,7 +723,7 @@ ubi_btNodePtr ubi_btLocate( ubi_btRootPtr RootPtr,
   {
   register ubi_btNodePtr p;
   ubi_btNodePtr   parent;
-  signed char     whichkid;
+  char            whichkid;
 
   /* Start by searching for a matching node. */
   p = TreeFind( FindMe,
@@ -746,9 +742,10 @@ ubi_btNodePtr ubi_btLocate( ubi_btRootPtr RootPtr,
       case ubi_trGT:            /* ...and then a jump to the right. */
         p = Border( RootPtr, FindMe, p, ubi_trRIGHT );
         return( Neighbor( p, ubi_trRIGHT ) );
+      default:
+        p = Border( RootPtr, FindMe, p, ubi_trLEFT );
+        return( p );
       }
-    p = Border( RootPtr, FindMe, p, ubi_trLEFT );
-    return( p );
     }
 
   /* Else, no match. */
@@ -761,7 +758,7 @@ ubi_btNodePtr ubi_btLocate( ubi_btRootPtr RootPtr,
    * Remaining possibilities are LT and GT (including LE & GE).
    */
   if( (ubi_trLT == CompOp) || (ubi_trLE == CompOp) )
-    return( (ubi_trLEFT  == whichkid) ? Neighbor( parent, whichkid ) : parent );
+    return( (ubi_trLEFT == whichkid) ? Neighbor( parent, whichkid ) : parent );
   else
     return( (ubi_trRIGHT == whichkid) ? Neighbor( parent, whichkid ) : parent );
   } /* ubi_btLocate */
@@ -866,7 +863,7 @@ ubi_btNodePtr ubi_btFirstOf( ubi_btRootPtr RootPtr,
    */
   {
   /* If our starting point is invalid, return NULL. */
-  if( !p || ubi_trNormalize( (*(RootPtr->cmp))( MatchMe, p ) != ubi_trEQUAL ) )
+  if( !p || ubi_trAbNormal( (*(RootPtr->cmp))( MatchMe, p ) != ubi_trEQUAL ) )
     return( NULL );
   return( Border( RootPtr, MatchMe, p, ubi_trLEFT ) );
   } /* ubi_btFirstOf */
@@ -891,7 +888,7 @@ ubi_btNodePtr ubi_btLastOf( ubi_btRootPtr RootPtr,
    */
   {
   /* If our starting point is invalid, return NULL. */
-  if( !p || ubi_trNormalize( (*(RootPtr->cmp))( MatchMe, p ) != ubi_trEQUAL ) )
+  if( !p || ubi_trAbNormal( (*(RootPtr->cmp))( MatchMe, p ) != ubi_trEQUAL ) )
     return( NULL );
   return( Border( RootPtr, MatchMe, p, ubi_trRIGHT ) );
   } /* ubi_btLastOf */
@@ -990,8 +987,6 @@ ubi_btNodePtr ubi_btLeafNode( ubi_btNodePtr leader )
    *          in pointers to nodes other than the root node each time.  A
    *          pointer to any node in the tree will do.  Of course, if you
    *          pass a pointer to a leaf node you'll get the same thing back.
-   *        + If using a splay tree, splaying the tree will tend to randomize
-   *          things a bit too.  See ubi_SplayTree for more info.
    *
    * ------------------------------------------------------------------------ **
    */
@@ -1001,10 +996,8 @@ ubi_btNodePtr ubi_btLeafNode( ubi_btNodePtr leader )
 
   while( NULL != leader )
     {
-    /* The next line is a weak attempt at randomizing. */
-    whichway = ((int)leader & 0x0010) ? whichway : ubi_trRevWay(whichway);
     follower = leader;
-    leader   = leader->Link[ whichway ];
+    leader   = follower->Link[ whichway ];
     if( NULL == leader )
       {
       whichway = ubi_trRevWay( whichway );
@@ -1043,4 +1036,5 @@ int ubi_btModuleID( int size, char *list[] )
   return( 0 );
   } /* ubi_btModuleID */
 
+
 /* ========================================================================== */
index d5032b58a21d2ef678c7fa8da430b1cf9212f6a0..4b918a46096c7379c3ab7d732a64d5e751ad844d 100644 (file)
@@ -8,7 +8,7 @@
  *  Email:  crh@ubiqx.mn.org
  * -------------------------------------------------------------------------- **
  *
- *  This module implements simple binary trees.
+ *  This module implements a simple binary tree.
  *
  * -------------------------------------------------------------------------- **
  *
  * -------------------------------------------------------------------------- **
  *
  * Log: ubi_BinTree.h,v
- * Revision 3.0  1997/12/08 06:49:15  crh
- * This is a new major revision level for all ubiqx binary tree modules.
- * In previous releases, the ubi_trNode structure looked like this:
- *
- *   typedef struct ubi_btNodeStruct
- *     {
- *     struct ubi_btNodeStruct *Link[3];
- *     signed char              gender;
- *     } ubi_btNode;
- *
- * As a result, the pointers were indexed as
- *
- *   Link[0] == Left Child
- *   Link[1] == Parent
- *   Link[2] == Right Child
- *
- * With this release, the node structure changes to:
- *
- *   typedef struct ubi_btNodeStruct
- *     {
- *     struct ubi_btNodeStruct *leftlink
- *     struct ubi_btNodeStruct *Link[2];
- *     signed char              gender;
- *     } ubi_btNode;
- *
- * The leftlink field is used as a place holder, and the pointers are now
- * index as
- *
- *   Link[-1] == Left Child  (aka. leftlink)
- *   Link[ 0] == Parent
- *   Link[ 1] == Right Child
- *
- * which is much nicer.  Doing things this way removes the need to shift
- * values between the two numbering schemes, thus removing one macro,
- * simplifying another, and getting rid of a whole bunch of increment &
- * decrement operations.
- *
- * Revision 2; 1995/02/27 - 1997/12/07 included:
- *  - The addition of the ModuleID static string and ubi_ModuleID() function.
- *  - The addition of the public functions FirstOf() and LastOf(). These
- *    functions are used with trees that allow duplicate keys.
- *  - The addition of the ubi_btLeafNode() function.
- *  - A rewrite of the Locate() function.
- *  - A change to the parameter list in function ubi_btInitTree().
- *  - Bugfixes.
- *
- * Revision 1; 93/10/15 - 95/02/27:
- * Revision 1 introduced a set of #define's that provide a single API to all
- * of the existing tree modules.  Each of these modules has a different name
- * prefix, as follows:
+ * Revision 2.5  1997/12/23 03:59:21  crh
+ * In this version, all constants & macros defined in the header file have
+ * the ubi_tr prefix.  Also cleaned up anything that gcc complained about
+ * when run with '-pedantic -fsyntax-only -Wall'.
+ *
+ * Revision 2.4  1997/07/26 04:11:14  crh
+ * + Just to be annoying I changed ubi_TRUE and ubi_FALSE to ubi_trTRUE
+ *   and ubi_trFALSE.
+ * + There is now a type ubi_trBool to go with ubi_trTRUE and ubi_trFALSE.
+ * + There used to be something called "ubi_TypeDefs.h".  I got rid of it.
+ * + Added function ubi_btLeafNode().
+ *
+ * Revision 2.3  1997/06/03 05:15:27  crh
+ * Changed TRUE and FALSE to ubi_TRUE and ubi_FALSE to avoid conflicts.
+ * Also changed the interface to function InitTree().  See the comments
+ * for this function for more information.
+ *
+ * Revision 2.2  1995/10/03 22:00:40  CRH
+ * Ubisized!
+ * 
+ * Revision 2.1  95/03/09  23:43:46  CRH
+ * Added the ModuleID static string and function.  These modules are now
+ * self-identifying.
+ * 
+ * Revision 2.0  95/02/27  22:00:33  CRH
+ * Revision 2.0 of this program includes the following changes:
+ *
+ *     1)  A fix to a major typo in the RepaceNode() function.
+ *     2)  The addition of the static function Border().
+ *     3)  The addition of the public functions FirstOf() and LastOf(), which
+ *         use Border(). These functions are used with trees that allow
+ *         duplicate keys.
+ *     4)  A complete rewrite of the Locate() function.  Locate() now accepts
+ *         a "comparison" operator.
+ *     5)  Overall enhancements to both code and comments.
+ *
+ * I decided to give this a new major rev number because the interface has
+ * changed.  In particular, there are two new functions, and changes to the
+ * Locate() function.
+ *
+ * Revision 1.0  93/10/15  22:55:04  CRH
+ * With this revision, I have added a set of #define's that provide a single,
+ * standard API to all existing tree modules.  Until now, each of the three
+ * existing modules had a different function and typedef prefix, as follows:
  *
  *       Module        Prefix
  *     ubi_BinTree     ubi_bt
  *     ubi_AVLtree     ubi_avl
  *     ubi_SplayTree   ubi_spt
  *
- * Only those portions of the base module (ubi_BinTree) that are superceeded
- * in the descendant module have new names.  For example, the AVL node
- * structure in ubi_AVLtree.h is named "ubi_avlNode", but the root structure
- * is still "ubi_btRoot".  Using SplayTree, the locate function is called
- * "ubi_sptLocate", but the next and previous functions remained "ubi_btNext"
- * and "ubi_btPrev".
+ * To further complicate matters, only those portions of the base module
+ * (ubi_BinTree) that were superceeded in the new module had the new names.
+ * For example, if you were using ubi_AVLtree, the AVL node structure was
+ * named "ubi_avlNode", but the root structure was still "ubi_btRoot".  Using
+ * SplayTree, the locate function was called "ubi_sptLocate", but the next
+ * and previous functions remained "ubi_btNext" and "ubi_btPrev".
  *
- * This is confusing.
+ * This was not too terrible if you were familiar with the modules and knew
+ * exactly which tree model you wanted to use.  If you wanted to be able to
+ * change modules (for speed comparisons, etc), things could get messy very
+ * quickly.
  *
- * So, I added a set of defined names that get redefined in any of the
+ * So, I have added a set of defined names that get redefined in any of the
  * descendant modules.  To use this standardized interface in your code,
  * simply replace all occurances of "ubi_bt", "ubi_avl", and "ubi_spt" with
  * "ubi_tr".  The "ubi_tr" names will resolve to the correct function or
  * Note that the original names do still exist, and can be used if you wish
  * to write code directly to a specific module.  This should probably only be
  * done if you are planning to implement a new descendant type, such as
- * red/black trees, or if you plan to use two or more specific tree types
- * in the same piece of code.  CRH
+ * red/black trees.  CRH
  *
  *  V0.0 - June, 1991   -  Written by Christopher R. Hertel (CRH).
  *
  */
 
 /* -------------------------------------------------------------------------- **
- * Constants...
+ * Macros and constants.
  *
  *  General purpose:
  *    ubi_trTRUE  - Boolean TRUE.
  *    ubi_trOVERWRITE   - This flag indicates that an existing node may be
  *                        overwritten by a new node with a matching key.
  *    ubi_trDUPKEY      - This flag indicates that the tree allows duplicate
- *                        keys.  If the tree allows duplicates, the overwrite
- *                        flag is ignored.
+ *                        keys.  If the tree does allow duplicates, the
+ *                        overwrite flag is ignored.
  *
- *  Node link array index constants:
- *    (Each node has an array of three pointers; pointer to the left child,
- *    pointer to the right child, and a pointer back to the parent node.)
- *      ubi_trLEFT    - Left child pointer.
- *      ubi_trPARENT  - Parent pointer.
- *      ubi_trRIGHT   - Right child pointer.
- *      ubi_trEQUAL   - Synonym for PARENT.
+ *  Node link array index constants:  (Each node has an array of three
+ *  pointers.  One to the left, one to the right, and one back to the
+ *  parent.)
+ *    ubi_trLEFT    - Left child pointer.
+ *    ubi_trPARENT  - Parent pointer.
+ *    ubi_trRIGHT   - Right child pointer.
+ *    ubi_trEQUAL   - Synonym for PARENT.
  *
  *  ubi_trCompOps:  These values are used in the ubi_trLocate() function.
  *    ubi_trLT  - request the first instance of the greatest key less than
  *                or equal to the search key.
  *    ubi_trGT  - request the first instance of the first key that is greater
  *                than the search key.
+ * -------------------------------------------------------------------------- **
  */
 
 #define ubi_trTRUE  0xFF
 #define ubi_trDUPKEY    0x02        /* Turn on allow duplicate keys */
 
 /* Pointer array index constants... */
-#define ubi_trLEFT   -1
-#define ubi_trPARENT  0
-#define ubi_trRIGHT   1
-#define ubi_trEQUAL   ubi_trPARENT
+#define ubi_trLEFT   0x00
+#define ubi_trPARENT 0x01
+#define ubi_trRIGHT  0x02
+#define ubi_trEQUAL  ubi_trPARENT
 
-typedef enum
-  {
+typedef enum {
   ubi_trLT = 1,
   ubi_trLE,
   ubi_trEQ,
@@ -171,57 +167,59 @@ typedef enum
   } ubi_trCompOps;
 
 /* -------------------------------------------------------------------------- **
- * Macros...
- *  ubi_trNormalize() - "Normalize" a value with respect to ubi_trLEFT,
- *                      ubi_trRIGHT, and ubi_trPARENT.  This macro calls
- *                      ubi_btSgn() to convert the input to -1, 0, or 1.
- *                      The resultant value is returned as a signed char.
- *
- *  ubi_trRevWay()    - converts ubi_trLEFT to ubi_trRIGHT and vice versa.
- *                      ubi_trPARENT (ubi_trEQUAL) is left as is.
- *
- *  ubi_trDups_OK()   - returns TRUE if the tree allows duplicates.
- *
- *  ubi_trOvwt_OK()   - returns TRUE if the overwrite flag is on.  Note
- *                      that overwrites will not occur in a tree that
- *                      allows duplicates.
+ * These three macros allow simple manipulation of pointer index values (LEFT,
+ * RIGHT, and PARENT).
+ *
+ *    Normalize() -  converts {LEFT, PARENT, RIGHT} into {-1, 0 ,1}.  C
+ *                   uses {negative, zero, positive} values to indicate
+ *                   {less than, equal to, greater than}.
+ *    AbNormal()  -  converts {negative, zero, positive} to {LEFT, PARENT,
+ *                   RIGHT} (opposite of Normalize()).  Note: C comparison
+ *                   functions, such as strcmp(), return {negative, zero,
+ *                   positive} values, which are not necessarily {-1, 0,
+ *                   1}.  This macro uses the the ubi_btSgn() function to
+ *                   compensate.
+ *    RevWay()    -  converts LEFT to RIGHT and RIGHT to LEFT.  PARENT (EQUAL)
+ *                   is left as is.
+ * -------------------------------------------------------------------------- **
  */
+#define ubi_trNormalize(W) ((char)( (W) - ubi_trEQUAL ))
+#define ubi_trAbNormal(W)  ((char)( ((char)ubi_btSgn( W )) + ubi_trEQUAL ))
+#define ubi_trRevWay(W)    ((char)( ubi_trEQUAL - ((W) - ubi_trEQUAL) ))
 
-#define ubi_trNormalize(W) ((signed char)ubi_btSgn(W))
-#define ubi_trRevWay(W) (-(W))
-
+/* -------------------------------------------------------------------------- **
+ * These macros allow us to quickly read the values of the OVERWRITE and
+ * DUPlicate KEY bits of the tree root flags field.
+ * -------------------------------------------------------------------------- **
+ */
 #define ubi_trDups_OK(A) \
-        ((ubi_trDUPKEY & ((A)->flags))   ? (ubi_trTRUE) : (ubi_trFALSE))
+        ((ubi_trDUPKEY & ((A)->flags))?(ubi_trTRUE):(ubi_trFALSE))
 #define ubi_trOvwt_OK(A) \
-        ((ubi_trOVERWRITE & ((A)->flags))? (ubi_trTRUE) : (ubi_trFALSE))
-
+        ((ubi_trOVERWRITE & ((A)->flags))?(ubi_trTRUE):(ubi_trFALSE))
 
 /* -------------------------------------------------------------------------- **
  * Typedefs...
  * 
- * ubi_trBool     - Your typcial true or false...
+ * ubi_trBool   - Your typcial true or false...
  *
- * ubi_btItemPtr  - The Item Pointer is a generic pointer.  It is used to
- *                  indicate a key for which to search within the tree.
- *                  The ubi_trFind(), ubi_trLocate(), and  ubi_trInsert()
- *                  functions all perform searches.
+ * Item Pointer:  The ubi_btItemPtr is a generic pointer. It is used to
+ *                indicate a key that is being searched for within the tree.
+ *                Searching occurs whenever the ubi_trFind(), ubi_trLocate(),
+ *                or ubi_trInsert() functions are called.
+ * -------------------------------------------------------------------------- **
  */
 
-typedef unsigned char ubi_trBool;   /* Our own name for "boolean".            */
+typedef unsigned char ubi_trBool;
 
-typedef void *ubi_btItemPtr;        /* A pointer to (key) data within a node. */
+typedef void *ubi_btItemPtr;              /* A pointer to data within a node. */
 
-/* -------------------------------------------------------------------------- **
- * Typedefs continued...
- *
+/*  ------------------------------------------------------------------------- **
  *  Binary Tree Node Structure:  This structure defines the basic elements of
  *       the tree nodes.  In general you *SHOULD NOT PLAY WITH THESE FIELDS*!
  *       But, of course, I have to put the structure into this header so that
  *       you can use it as a building block.
  *
  *  The fields are as follows:
- *    leftlink -  pointer to the left child of the node.  This field will
- *                be accessed as Link[-1].
  *    Link     -  an array of pointers.  These pointers are manipulated by
  *                the BT routines.  The pointers indicate the left and right
  *                child nodes and the parent node.  By keeping track of the
@@ -232,22 +230,18 @@ typedef void *ubi_btItemPtr;        /* A pointer to (key) data within a node. */
  *    gender   -  a one-byte field indicating whether the node is the RIGHT or
  *                LEFT child of its parent.  If the node is the root of the
  *                tree, gender will be PARENT.
+ *  ------------------------------------------------------------------------- **
  */
-
-typedef struct ubi_btNodeStruct
-  {
-  struct ubi_btNodeStruct *leftlink;    /* Will be accessed as Link[-1].      */
-  struct ubi_btNodeStruct *Link[2];     /* Parent & Right links.              */
-  signed char              gender;      /* Indicates Left/Right of parent.    */
+typedef struct ubi_btNodeStruct {
+  struct ubi_btNodeStruct *Link[ 3 ];
+  char                     gender;
   } ubi_btNode;
 
 typedef ubi_btNode *ubi_btNodePtr;     /* Pointer to an ubi_btNode structure. */
 
-/* -------------------------------------------------------------------------- **
- * Typedefs continued...
- *
- *  The next three typedefs define standard function types used by the binary
- *  tree management routines.  In particular:
+/*  ------------------------------------------------------------------------- **
+ * The next three typedefs define standard function types used by the binary
+ * tree management routines.  In particular:
  *
  *    ubi_btCompFunc    is a pointer to a comparison function.  Comparison
  *                      functions are passed an ubi_btItemPtr and an
@@ -267,6 +261,7 @@ typedef ubi_btNode *ubi_btNodePtr;     /* Pointer to an ubi_btNode structure. */
  *                      mean anything that you want it to mean.  Just remember
  *                      that the tree *will* be destroyed and that none of the
  *                      node pointers will be valid any more.
+ *  ------------------------------------------------------------------------- **
  */
 
 typedef  int (*ubi_btCompFunc)( ubi_btItemPtr, ubi_btNodePtr );
@@ -276,10 +271,8 @@ typedef void (*ubi_btActionRtn)( ubi_btNodePtr, void * );
 typedef void (*ubi_btKillNodeRtn)( ubi_btNodePtr );
 
 /* -------------------------------------------------------------------------- **
- * Typedefs continued...
- *
- *  Tree Root Structure: This structure gives us a convenient handle for
- *                       accessing whole AVL trees.  The fields are:
+ * Tree Root Structure: This structure gives us a convenient handle for
+ *                      accessing whole AVL trees.  The fields are:
  *    root  -  A pointer to the root node of the AVL tree.
  *    count -  A count of the number of nodes stored in the tree.
  *    cmp   -  A pointer to the comparison routine to be used when building or
@@ -293,15 +286,13 @@ typedef void (*ubi_btKillNodeRtn)( ubi_btNodePtr );
  *         (bit 0x02)       allowed to contain nodes with duplicate keys.
  *
  *       NOTE: ubi_trInsert() tests ubi_trDUPKEY before ubi_trOVERWRITE.
- *             If duplicate keys are allowed, then no entry will be
- *             overwritten.
  *
- *  All of these values are set when you initialize the root structure by
- *  calling ubi_trInitTree().
+ * All of these values are set when you initialize the root structure by
+ * calling ubi_trInitTree().
+ * -------------------------------------------------------------------------- **
  */
 
-typedef struct
-  {
+typedef struct {
   ubi_btNodePtr  root;     /* A pointer to the root node of the tree       */
   unsigned long  count;    /* A count of the number of nodes in the tree   */
   ubi_btCompFunc cmp;      /* A pointer to the tree's comparison function  */
@@ -321,15 +312,15 @@ long ubi_btSgn( long x );
    *
    *  Input:  x - a signed long integer value.
    *
-   *  Output: -1, 0, or 1 representing the "sign" of x as follows:
+   *  Output: the "sign" of x, represented as follows:
    *            -1 == negative
    *             0 == zero (no sign)
    *             1 == positive
    *
-   *  Notes:  This utility is provided in order to facilitate the conversion
-   *          of C comparison function return values into BinTree direction
-   *          values: {ubi_trLEFT, ubi_trPARENT, ubi_trEQUAL}.  It is
-   *          incorporated into the Normalize() conversion macro.
+   * Note: This utility is provided in order to facilitate the conversion
+   *       of C comparison function return values into BinTree direction
+   *       values: {LEFT, PARENT, EQUAL}.  It is INCORPORATED into the
+   *       AbNormal() conversion macro!
    *
    * ------------------------------------------------------------------------ **
    */
@@ -344,9 +335,9 @@ ubi_btNodePtr ubi_btInitNode( ubi_btNodePtr NodePtr );
    * ------------------------------------------------------------------------ **
    */
 
-ubi_btRootPtr ubi_btInitTree( ubi_btRootPtr   RootPtr,
-                              ubi_btCompFunc  CompFunc,
-                              unsigned char   Flags );
+ubi_btRootPtr  ubi_btInitTree( ubi_btRootPtr   RootPtr,
+                               ubi_btCompFunc  CompFunc,
+                               unsigned char   Flags );
   /* ------------------------------------------------------------------------ **
    * Initialize the fields of a Tree Root header structure.
    *  
@@ -648,8 +639,6 @@ ubi_btNodePtr ubi_btLeafNode( ubi_btNodePtr leader );
    *          in pointers to nodes other than the root node each time.  A
    *          pointer to any node in the tree will do.  Of course, if you
    *          pass a pointer to a leaf node you'll get the same thing back.
-   *        + If using a splay tree, splaying the tree will tend to randomize
-   *          things a bit too.  See ubi_SplayTree for more info.
    *
    * ------------------------------------------------------------------------ **
    */
index fb4cc9f7c8e7c15ad68d0fa35f48e30846ac4af1..799996b6cc3739c00cca54e1ce2a3409bc14040d 100644 (file)
  * -------------------------------------------------------------------------- **
  *
  * Log: ubi_SplayTree.c,v
- * Revision 3.0  1997/12/08 05:32:28  crh
- * This is a new major revision level because of a redesign of the handling
- * of the pointers in the ubi_trNode structure.  See ubi_BinTree for more
- * info.
+ * Revision 2.6  1997/12/23 04:01:12  crh
+ * In this version, all constants & macros defined in the header file have
+ * the ubi_tr prefix.  Also cleaned up anything that gcc complained about
+ * when run with '-pedantic -fsyntax-only -Wall'.
  *
- * Revision 2;  1995/02/27 - 1997/12/07:
- * Major changes: added the function ubi_sptSplay().
+ * Revision 2.5  1997/07/26 04:15:42  crh
+ * + Cleaned up a few minor syntax annoyances that gcc discovered for me.
+ * + Changed ubi_TRUE and ubi_FALSE to ubi_trTRUE and ubi_trFALSE.
  *
- * Revision 1; 93/10/15 - 95/02/27:
- * Added the ubi_tr defines.  See ubi_BinTree.h for more info.
+ * Revision 2.4  1997/06/03 04:42:21  crh
+ * Changed TRUE and FALSE to ubi_TRUE and ubi_FALSE to avoid causing
+ * problems.
+ *
+ * Revision 2.3  1995/10/03 22:19:07  CRH
+ * Ubisized!
+ * Also, added the function ubi_sptSplay().
+ *
+ * Revision 2.1  95/03/09  23:54:42  CRH
+ * Added the ModuleID static string and function.  These modules are now
+ * self-identifying.
+ * 
+ * Revision 2.0  95/02/27  22:34:46  CRH
+ * This module was updated to match the interface changes made to the
+ * ubi_BinTree module.  In particular, the interface to the Locate() function
+ * has changed.  See ubi_BinTree for more information on changes and new
+ * functions.
+ *
+ * The revision number was also upped to match ubi_BinTree.
+ *
+ * Revision 1.1  93/10/18  20:35:16  CRH
+ * I removed the hard-coded logical device names from the include file
+ * specifications.  CRH
+ *
+ * Revision 1.0  93/10/15  23:00:15  CRH
+ * With this revision, I have added a set of #define's that provide a single,
+ * standard API to all existing tree modules.  Until now, each of the three
+ * existing modules had a different function and typedef prefix, as follows:
+ *
+ *       Module        Prefix
+ *     ubi_BinTree     ubi_bt
+ *     ubi_AVLtree     ubi_avl
+ *     ubi_SplayTree   ubi_spt
+ *
+ * To further complicate matters, only those portions of the base module
+ * (ubi_BinTree) that were superceeded in the new module had the new names.
+ * For example, if you were using ubi_AVLtree, the AVL node structure was
+ * named "ubi_avlNode", but the root structure was still "ubi_btRoot".  Using
+ * SplayTree, the locate function was called "ubi_sptLocate", but the next
+ * and previous functions remained "ubi_btNext" and "ubi_btPrev".
+ *
+ * This was not too terrible if you were familiar with the modules and knew
+ * exactly which tree model you wanted to use.  If you wanted to be able to
+ * change modules (for speed comparisons, etc), things could get messy very
+ * quickly.
+ *
+ * So, I have added a set of defined names that get redefined in any of the
+ * descendant modules.  To use this standardized interface in your code,
+ * simply replace all occurances of "ubi_bt", "ubi_avl", and "ubi_spt" with
+ * "ubi_tr".  The "ubi_tr" names will resolve to the correct function or
+ * datatype names for the module that you are using.  Just remember to
+ * include the header for that module in your program file.  Because these
+ * names are handled by the preprocessor, there is no added run-time
+ * overhead.
+ *
+ * Note that the original names do still exist, and can be used if you wish
+ * to write code directly to a specific module.  This should probably only be
+ * done if you are planning to implement a new descendant type, such as
+ * red/black trees.  CRH
+ *
+ * Revision 0.1  93/04/25  22:03:32  CRH
+ * Simply changed the <exec/types.h> #include reference the .c file to
+ * use <stdlib.h> instead.  The latter is portable, the former is not.
  *
  * Revision 0.0  93/04/21  23:05:52  CRH
  * Initial version, written by Christopher R. Hertel.
  */
 
 static char ModuleID[] = "ubi_SplayTree\n\
-\tRevision: 3.0\n\
-\tDate: 1997/12/08 05:32:28\n\
+\tRevision: 2.6\n\
+\tDate: 1997/12/23 04:01:12\n\
 \tAuthor: crh\n";
 
 
@@ -87,18 +149,18 @@ static void Rotate( ubi_btNodePtr p )
   {
   ubi_btNodePtr parentp;
   ubi_btNodePtr tmp;
-  signed char   way;
-  signed char   revway;
+  char          way;
+  char          revway;
 
   parentp = p->Link[ubi_trPARENT];    /* Find parent. */
 
   if( parentp )                 /* If no parent, then we're already the root. */
     {
-    way     = p->gender;
-    revway  = ubi_trRevWay(way);
-    tmp     = p->Link[revway];
+    way    = p->gender;
+    revway = ubi_trRevWay(way);
+    tmp    = p->Link[(int)revway];
 
-    parentp->Link[way]  = tmp;
+    parentp->Link[(int)way] = tmp;
     if( tmp )
       {
       tmp->Link[ubi_trPARENT] = parentp;
@@ -109,11 +171,11 @@ static void Rotate( ubi_btNodePtr p )
     p->Link[ubi_trPARENT] = tmp;
     p->gender             = parentp->gender;
     if( tmp )
-      tmp->Link[p->gender] = p;
+      tmp->Link[(int)(p->gender)] = p;
 
     parentp->Link[ubi_trPARENT] = p;
     parentp->gender             = revway;
-    p->Link[revway]             = parentp;
+    p->Link[(int)revway]        = parentp;
     }
   } /* Rotate */
 
@@ -141,7 +203,7 @@ static ubi_btNodePtr Splay( ubi_btNodePtr SplayWithMe )
         Rotate( SplayWithMe );
       }
     Rotate( SplayWithMe );                            /* Zig */
-    } 
+    } /* while */
   return( SplayWithMe );
   } /* Splay */
 
@@ -238,9 +300,9 @@ ubi_btNodePtr ubi_sptRemove( ubi_btRootPtr RootPtr, ubi_btNodePtr DeadNode )
     ubi_btNodePtr q = DeadNode->Link[ubi_trRIGHT];
 
     p->Link[ubi_trPARENT] = NULL;           /* Left subtree node becomes root.*/
-    p->gender       = ubi_trPARENT;
-    p               = ubi_btLast( p );      /* Find rightmost left tree node..*/
-    p->Link[ubi_trRIGHT]  = q;              /* ...attach right tree.          */
+    p->gender             = ubi_trPARENT;
+    p                     = ubi_btLast( p );  /* Find rightmost left node...  */
+    p->Link[ubi_trRIGHT]  = q;                /* ...attach right tree.        */
     if( q )
       q->Link[ubi_trPARENT] = p;
     RootPtr->root   = Splay( p );           /* Resplay at p.                  */
@@ -368,7 +430,7 @@ void ubi_sptSplay( ubi_btRootPtr RootPtr,
    *          Splaying the tree will not damage it (assuming that I've done
    *          *my* job), but there is overhead involved.  I don't recommend
    *          that you use this function unless you understand the underlying
-   *          Splay Tree.
+   *          Splay Tree principles involved.
    * ------------------------------------------------------------------------ **
    */
   {
index 089fdc9d689198eecf6ee8a187cd8d037a9adc29..d45c32fce83d9858ca2a72ad2d4bcaaf335b278e 100644 (file)
  * -------------------------------------------------------------------------- **
  *
  * Log: ubi_SplayTree.h,v
- * Revision 3.0  1997/12/08 05:32:35  crh
- * This is a new major revision level because of a redesign of the handling
- * of the pointers in the ubi_trNode structure.  See ubi_BinTree for more
- * info.
+ * Revision 2.6  1997/12/23 04:02:20  crh
+ * In this version, all constants & macros defined in the header file have
+ * the ubi_tr prefix.  Also cleaned up anything that gcc complained about
+ * when run with '-pedantic -fsyntax-only -Wall'.
  *
- * Revision 2;  1995/02/27 - 1997/12/07:
- * Major changes: added the function ubi_sptSplay().
+ * Revision 2.5  1997/07/26 04:15:46  crh
+ * + Cleaned up a few minor syntax annoyances that gcc discovered for me.
+ * + Changed ubi_TRUE and ubi_FALSE to ubi_trTRUE and ubi_trFALSE.
  *
- * Revision 1; 93/10/15 - 95/02/27:
- * Added the ubi_tr defines.  See ubi_BinTree.h for more info.
+ * Revision 2.4  1997/06/03 05:22:56  crh
+ * Changed TRUE and FALSE to ubi_TRUE and ubi_FALSE to avoid causing
+ * problems.
+ *
+ * Revision 2.3  1995/10/03 22:19:37  CRH
+ * Ubisized!
+ * Also, added the function ubi_sptSplay().
+ *
+ * Revision 2.1  95/03/09  23:55:04  CRH
+ * Added the ModuleID static string and function.  These modules are now
+ * self-identifying.
+ * 
+ * Revision 2.0  95/02/27  22:34:55  CRH
+ * This module was updated to match the interface changes made to the
+ * ubi_BinTree module.  In particular, the interface to the Locate() function
+ * has changed.  See ubi_BinTree for more information on changes and new
+ * functions.
+ *
+ * The revision number was also upped to match ubi_BinTree.
+ *
+ *
+ * Revision 1.0  93/10/15  22:59:36  CRH
+ * With this revision, I have added a set of #define's that provide a single,
+ * standard API to all existing tree modules.  Until now, each of the three
+ * existing modules had a different function and typedef prefix, as follows:
+ *
+ *       Module        Prefix
+ *     ubi_BinTree     ubi_bt
+ *     ubi_AVLtree     ubi_avl
+ *     ubi_SplayTree   ubi_spt
+ *
+ * To further complicate matters, only those portions of the base module
+ * (ubi_BinTree) that were superceeded in the new module had the new names.
+ * For example, if you were using ubi_AVLtree, the AVL node structure was
+ * named "ubi_avlNode", but the root structure was still "ubi_btRoot".  Using
+ * SplayTree, the locate function was called "ubi_sptLocate", but the next
+ * and previous functions remained "ubi_btNext" and "ubi_btPrev".
+ *
+ * This was not too terrible if you were familiar with the modules and knew
+ * exactly which tree model you wanted to use.  If you wanted to be able to
+ * change modules (for speed comparisons, etc), things could get messy very
+ * quickly.
+ *
+ * So, I have added a set of defined names that get redefined in any of the
+ * descendant modules.  To use this standardized interface in your code,
+ * simply replace all occurances of "ubi_bt", "ubi_avl", and "ubi_spt" with
+ * "ubi_tr".  The "ubi_tr" names will resolve to the correct function or
+ * datatype names for the module that you are using.  Just remember to
+ * include the header for that module in your program file.  Because these
+ * names are handled by the preprocessor, there is no added run-time
+ * overhead.
+ *
+ * Note that the original names do still exist, and can be used if you wish
+ * to write code directly to a specific module.  This should probably only be
+ * done if you are planning to implement a new descendant type, such as
+ * red/black trees.  CRH
  *
  * Revision 0.0  93/04/21  23:07:13  CRH
  * Initial version, written by Christopher R. Hertel.
@@ -217,7 +272,7 @@ void ubi_sptSplay( ubi_btRootPtr RootPtr,
    *          Splaying the tree will not damage it (assuming that I've done
    *          *my* job), but there is overhead involved.  I don't recommend
    *          that you use this function unless you understand the underlying
-   *          Splay Tree.
+   *          Splay Tree principles involved.
    * ------------------------------------------------------------------------ **
    */