Updates to all of these base level modules.
authorChristopher R. Hertel <crh@samba.org>
Tue, 10 Mar 1998 15:39:41 +0000 (15:39 +0000)
committerChristopher R. Hertel <crh@samba.org>
Tue, 10 Mar 1998 15:39:41 +0000 (15:39 +0000)
Trees: Previously, the AVL node type was different than the node type used
       in the BinTree and SplayTree modules.  It requires an additional
       field to maintain AVL balance information.  I merged that field into
       the base type (in ubi_BinTree.h) so that all three use the same
       node type.  On most systems this will have zero effect on the node
       size, due to word alignment.  The change allowed me to remove a
       bigbunch of redundant code, which makes the AVL module smaller and
       cleaner.
Linked Lists:  I combined ubi_StackQueue into ubi_sLinkList.  The interface
       has changed a tiny bit.  I added macros to ubi_dLinkList to round
       it out a bit.

I have verified that the few Samba modules that use these tools (so far)
do not have any problems with the changes.

Chris -)-----
(This used to be commit 599a29401defded32358dfae18e54704c0428f38)

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
source3/ubiqx/ubi_dLinkList.c
source3/ubiqx/ubi_dLinkList.h
source3/ubiqx/ubi_sLinkList.c
source3/ubiqx/ubi_sLinkList.h

index 2cd8d1cbedf02390c99601f1755c3329c05ac388..c02765f4413e127f5f40e3a4dfef230daad48437 100644 (file)
@@ -1,7 +1,7 @@
 /* ========================================================================== **
  *                              ubi_AVLtree.c
  *
- *  Copyright (C) 1991-1997 by Christopher R. Hertel
+ *  Copyright (C) 1991-1998 by Christopher R. Hertel
  *
  *  Email: crh@ubiqx.mn.org
  * -------------------------------------------------------------------------- **
  * -------------------------------------------------------------------------- **
  *
  * Log: ubi_AVLtree.c,v
+ * Revision 4.0  1998/03/10 03:37:09  crh
+ * Major changes.
+ * By adding the AVL balance field to the base ubi_btNode structure, I no
+ * longer need AVL-specific ReplaceNode(), SwapNodes(), and InitNode()
+ * functions.  The Remove() function is also simplified.  It's all much
+ * cleaner.
+ * This is rev. 4.0.  The 3.x series was dropped.
+ *
  * 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
  *
  * 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".
+ * For example, if you were using ubi_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
  */
 
 static char ModuleID[] = "ubi_AVLtree\n\
-\tRevision: 2.5\n\
-\tDate: 1997/12/23 04:00:42\n\
+\tRevision: 4.0\n\
+\tDate: 1998/03/10 03:37:09\n\
 \tAuthor: crh\n";
 
 /* ========================================================================== **
@@ -147,7 +154,7 @@ static char ModuleID[] = "ubi_AVLtree\n\
  * -------------------------------------------------------------------------- **
  */
 
-static ubi_avlNodePtr L1( ubi_avlNodePtr p )
+static ubi_btNodePtr L1( ubi_btNodePtr p )
   /* ------------------------------------------------------------------------ **
    * Single rotate left.
    *
@@ -157,7 +164,7 @@ static ubi_avlNodePtr L1( ubi_avlNodePtr p )
    * ------------------------------------------------------------------------ **
    */
   {
-  ubi_avlNodePtr tmp;
+  ubi_btNodePtr tmp;
 
   tmp                      = p->Link[ubi_trRIGHT];
   p->Link[ubi_trRIGHT]     = tmp->Link[ubi_trLEFT];
@@ -179,7 +186,7 @@ static ubi_avlNodePtr L1( ubi_avlNodePtr p )
   return( tmp );
   } /* L1 */
 
-static ubi_avlNodePtr R1( ubi_avlNodePtr p )
+static ubi_btNodePtr R1( ubi_btNodePtr p )
   /* ------------------------------------------------------------------------ **
    * Single rotate right.
    *
@@ -189,7 +196,7 @@ static ubi_avlNodePtr R1( ubi_avlNodePtr p )
    * ------------------------------------------------------------------------ **
    */
   {
-  ubi_avlNodePtr tmp;
+  ubi_btNodePtr tmp;
 
   tmp                      = p->Link[ubi_trLEFT];
   p->Link[ubi_trLEFT]      = tmp->Link[ubi_trRIGHT];
@@ -211,7 +218,7 @@ static ubi_avlNodePtr R1( ubi_avlNodePtr p )
   return( tmp );
   } /* R1 */
 
-static ubi_avlNodePtr L2( ubi_avlNodePtr tree )
+static ubi_btNodePtr L2( ubi_btNodePtr tree )
   /* ------------------------------------------------------------------------ **
    * Double rotate left.
    *
@@ -221,7 +228,7 @@ static ubi_avlNodePtr L2( ubi_avlNodePtr tree )
    * ------------------------------------------------------------------------ **
    */
   {
-  ubi_avlNodePtr tmp, newroot;
+  ubi_btNodePtr tmp, newroot;
 
   tmp                         = tree->Link[ubi_trRIGHT];
   newroot                     = tmp->Link[ubi_trLEFT];
@@ -263,7 +270,7 @@ static ubi_avlNodePtr L2( ubi_avlNodePtr tree )
   return( newroot );
   } /* L2 */
 
-static ubi_avlNodePtr R2( ubi_avlNodePtr tree )
+static ubi_btNodePtr R2( ubi_btNodePtr tree )
   /* ------------------------------------------------------------------------ **
    * Double rotate right.
    *
@@ -273,7 +280,7 @@ static ubi_avlNodePtr R2( ubi_avlNodePtr tree )
    * ------------------------------------------------------------------------ **
    */
   {
-  ubi_avlNodePtr tmp, newroot;
+  ubi_btNodePtr tmp, newroot;
 
   tmp                         = tree->Link[ubi_trLEFT];
   newroot                     = tmp->Link[ubi_trRIGHT];
@@ -316,7 +323,7 @@ static ubi_avlNodePtr R2( ubi_avlNodePtr tree )
   } /* R2 */
 
 
-static ubi_avlNodePtr Adjust( ubi_avlNodePtr p, char LorR )
+static ubi_btNodePtr Adjust( ubi_btNodePtr p, char LorR )
   /* ------------------------------------------------------------------------ **
    * Adjust the balance value at node *p.  If necessary, rotate the subtree
    * rooted at p.
@@ -349,9 +356,9 @@ static ubi_avlNodePtr Adjust( ubi_avlNodePtr p, char LorR )
   return( p );
   } /* Adjust */
 
-static ubi_avlNodePtr Rebalance( ubi_avlNodePtr Root,
-                                 ubi_avlNodePtr subtree,
-                                 char           LorR )
+static ubi_btNodePtr Rebalance( ubi_btNodePtr Root,
+                                ubi_btNodePtr subtree,
+                                char          LorR )
   /* ------------------------------------------------------------------------ **
    * Rebalance the tree following an insertion.
    *
@@ -387,9 +394,9 @@ static ubi_avlNodePtr Rebalance( ubi_avlNodePtr Root,
   return( Root );
   } /* Rebalance */
 
-static ubi_avlNodePtr Debalance( ubi_avlNodePtr Root,
-                                 ubi_avlNodePtr subtree,
-                                 char           LorR )
+static ubi_btNodePtr Debalance( ubi_btNodePtr Root,
+                                ubi_btNodePtr subtree,
+                                char          LorR )
   /* ------------------------------------------------------------------------ **
    * Rebalance the tree following a deletion.
    *
@@ -428,125 +435,22 @@ static ubi_avlNodePtr Debalance( ubi_avlNodePtr Root,
   return( Root );
   } /* Debalance */
 
-
-/* -------------------------------------------------------------------------- **
- * The next two functions are used for general tree manipulation.  They are
- * each slightly different from their ubi_BinTree counterparts.
- * -------------------------------------------------------------------------- **
- */
-
-static void ReplaceNode( ubi_avlNodePtr *parent,
-                         ubi_avlNodePtr  oldnode,
-                         ubi_avlNodePtr  newnode )
-  /* ------------------------------------------------------------------------ **
-   * Remove node oldnode from the tree, replacing it with node newnode.
-   *
-   * Input:
-   *  parent   - A pointer to he parent pointer of the node to be
-   *             replaced.  <parent> may point to the Link[] field of
-   *             a parent node, or it may indicate the root pointer at
-   *             the top of the tree.
-   *  oldnode  - A pointer to the node that is to be replaced.
-   *  newnode  - A pointer to the node that is to be installed in the
-   *             place of <*oldnode>.
-   *
-   * Notes:    Don't forget to free oldnode.
-   *           The only difference between this function and the ubi_bt
-   *           version is that the node size is sizeof( ubi_avlNode ), not
-   *           sizeof( ubi_btNode ).
-   * ------------------------------------------------------------------------ **
-   */
-  {
-  register int i;
-  register int avlNodeSize = sizeof( ubi_avlNode );
-
-  for( i = 0; i < avlNodeSize; i++ )
-    ((unsigned char *)newnode)[i] = ((unsigned char *)oldnode)[i];
-  (*parent) = 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,
-                       ubi_avlNodePtr Node1,
-                       ubi_avlNodePtr Node2 )
-  /* ------------------------------------------------------------------------ **
-   * This function swaps two nodes in the tree.  Node1 will take the place of
-   * Node2, and Node2 will fill in the space left vacant by Node 1.
-   *
-   * Input:
-   *  RootPtr  - pointer to the tree header structure for this tree.
-   *  Node1    - \
-   *              > These are the two nodes which are to be swapped.
-   *  Node2    - /
-   *
-   * Notes:
-   *  This function does a three step swap, using a dummy node as a place
-   *  holder.  This function is used by ubi_avlRemove().
-   *  The only difference between this function and its ubi_bt counterpart
-   *  is that the nodes are ubi_avlNodes, not ubi_btNodes.
-   * ------------------------------------------------------------------------ **
-   */
-  {
-  ubi_avlNodePtr *Parent;
-  ubi_avlNode     dummy;
-  ubi_avlNodePtr  dummy_p = &dummy;
-
-  if( Node1->Link[ubi_trPARENT] )
-    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[(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[(int)(dummy_p->gender)]);
-  else
-    Parent = (ubi_avlNodePtr *)&(RootPtr->root);
-  ReplaceNode( Parent, dummy_p, Node2 );
-  } /* SwapNodes */
-
-
 /* ========================================================================== **
  *         Public, exported (ie. not static-ly declared) functions...
  * -------------------------------------------------------------------------- **
  */
 
-ubi_avlNodePtr ubi_avlInitNode( ubi_avlNodePtr NodePtr )
-  /* ------------------------------------------------------------------------ **
-   * Initialize a tree node.
-   *
-   *  Input:   NodePtr  - pointer to a ubi_btNode structure to be
-   *                      initialized.
-   *  Output:  a pointer to the initialized ubi_avlNode structure (ie. the
-   *           same as the input pointer).
-   * ------------------------------------------------------------------------ **
-   */
-  {
-  (void)ubi_btInitNode( (ubi_btNodePtr)NodePtr );
-  NodePtr->balance = ubi_trEQUAL;
-  return( NodePtr );
-  } /* ubi_avlInitNode */
-
-ubi_trBool ubi_avlInsert( ubi_btRootPtr   RootPtr,
-                          ubi_avlNodePtr  NewNode,
-                          ubi_btItemPtr   ItemPtr,
-                          ubi_avlNodePtr *OldNode )
+ubi_trBool ubi_avlInsert( ubi_btRootPtr  RootPtr,
+                          ubi_btNodePtr  NewNode,
+                          ubi_btItemPtr  ItemPtr,
+                          ubi_btNodePtr *OldNode )
   /* ------------------------------------------------------------------------ **
    * This function uses a non-recursive algorithm to add a new element to
    * the tree.
    *
    *  Input:   RootPtr  -  a pointer to the ubi_btRoot structure that indicates
    *                       the root of the tree to which NewNode is to be added.
-   *           NewNode  -  a pointer to an ubi_avlNode structure that is NOT
+   *           NewNode  -  a pointer to an ubi_btNode structure that is NOT
    *                       part of any tree.
    *           ItemPtr  -  A pointer to the sort key that is stored within
    *                       *NewNode.  ItemPtr MUST point to information stored
@@ -585,9 +489,10 @@ ubi_trBool ubi_avlInsert( ubi_btRootPtr   RootPtr,
    * ------------------------------------------------------------------------ **
    */
   {
-  ubi_avlNodePtr OtherP;
+  ubi_btNodePtr OtherP;
 
-  if( !(OldNode) ) OldNode = &OtherP;
+  if( !(OldNode) )
+    OldNode = &OtherP;
   if( ubi_btInsert( RootPtr,
                     (ubi_btNodePtr)NewNode,
                     ItemPtr,
@@ -598,7 +503,7 @@ ubi_trBool ubi_avlInsert( ubi_btRootPtr   RootPtr,
     else
       {
       NewNode->balance = ubi_trEQUAL;
-      RootPtr->root = (ubi_btNodePtr)Rebalance( (ubi_avlNodePtr)RootPtr->root,
+      RootPtr->root = (ubi_btNodePtr)Rebalance( (ubi_btNodePtr)RootPtr->root,
                                                 NewNode->Link[ubi_trPARENT],
                                                 NewNode->gender );
       }
@@ -607,8 +512,8 @@ ubi_trBool ubi_avlInsert( ubi_btRootPtr   RootPtr,
   return( ubi_trFALSE );      /* Failure: could not replace an existing node. */
   } /* ubi_avlInsert */
 
-ubi_avlNodePtr ubi_avlRemove( ubi_btRootPtr  RootPtr,
-                              ubi_avlNodePtr DeadNode )
+ubi_btNodePtr ubi_avlRemove( ubi_btRootPtr  RootPtr,
+                             ubi_btNodePtr  DeadNode )
   /* ------------------------------------------------------------------------ **
    * This function removes the indicated node from the tree, after which the
    * tree is rebalanced.
@@ -622,45 +527,15 @@ ubi_avlNodePtr ubi_avlRemove( ubi_btRootPtr  RootPtr,
    *
    *  Note:   The node MUST be in the tree indicated by RootPtr.  If not,
    *          strange and evil things will happen to your trees.
+   *
    * ------------------------------------------------------------------------ **
    */
   {
-  ubi_btNodePtr p,
-               *parentp;
-
-  /* if the node has both left and right subtrees, then we have to swap
-   * it with another node.
-   */
-  if( (DeadNode->Link[ubi_trLEFT]) && (DeadNode->Link[ubi_trRIGHT]) )
-    SwapNodes( RootPtr, DeadNode, ubi_trPrev( DeadNode ) );
-
-  /* The parent of the node to be deleted may be another node, or it may be
-   * the root of the tree.  Since we're not sure, it's best just to have
-   * a pointer to the parent pointer, whatever it is.
-   */
-  if( DeadNode->Link[ubi_trPARENT] )
-    parentp = (ubi_btNodePtr *)
-              &((DeadNode->Link[ubi_trPARENT])->Link[(int)(DeadNode->gender)]);
-  else
-    parentp = &( RootPtr->root );
-
-  /* Now link the parent to the only grand-child.  Patch up the gender and
-   * such, and rebalance.
-   */
-  if( ubi_trEQUAL == DeadNode->balance )
-    (*parentp) = NULL;
-  else
-    {
-    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,
-                                            DeadNode->Link[ubi_trPARENT],
-                                            DeadNode->gender );
-
-  (RootPtr->count)--;
+  /* Let the base binary tree module do the removal, then rebalance. */
+  if( ubi_btRemove( RootPtr, DeadNode ) )
+    RootPtr->root = Debalance( RootPtr->root,
+                               DeadNode->Link[ubi_trPARENT],
+                               DeadNode->gender );
   return( DeadNode );
   } /* ubi_avlRemove */
 
index ebae7f3c1316e53a3aae716741badd3c5149a82c..f99a78aa267559d0878c44ab3194cac53dab77e2 100644 (file)
@@ -3,7 +3,7 @@
 /* ========================================================================== **
  *                              ubi_AVLtree.h
  *
- *  Copyright (C) 1991-1997 by Christopher R. Hertel
+ *  Copyright (C) 1991-1998 by Christopher R. Hertel
  *
  *  Email: crh@ubiqx.mn.org
  * -------------------------------------------------------------------------- **
  *
  * -------------------------------------------------------------------------- **
  * Log: ubi_AVLtree.h,v
+ * Revision 4.0  1998/03/10 03:34:45  crh
+ * Major changes.
+ * By adding the AVL balance field to the base ubi_btNode structure, I no
+ * longer need AVL-specific ReplaceNode(), SwapNodes(), and InitNode()
+ * functions.  The Remove() function is also simplified.  It's all much
+ * cleaner.
+ * This is rev. 4.0.  The 3.x series was dropped.
+ *
  * 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
  *
  * 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".
+ * For example, if you were using ubi_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
 
 #include "ubi_BinTree.h"   /* Base erg binary tree support.       */
 
-/*  ------------------------------------------------------------------------- **
- *  AVL Tree Node Structure:  This structure defines the basic elements of
- *       the AVL 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 the structure as a building block.
- *
- *  The fields are as follows:
- *    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
- *                pointer, we avoid the need for recursive routines or hand-
- *                tooled stacks to keep track of our path back to the root.
- *                The use of these pointers is subject to change without
- *                notice.
- *    gender   -  For tree rebalancing purposes, it is necessary that each node
- *                know whether it is the left or right child of its parent, or
- *                if it is the root.  This information is stored in this field.
- *    balance  -  This field is also needed for AVL balancing purposes.  It
- *                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
-         *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 */
-
 /* -------------------------------------------------------------------------- **
  *  Function prototypes.
  * -------------------------------------------------------------------------- **
  */
 
-ubi_avlNodePtr ubi_avlInitNode( ubi_avlNodePtr NodePtr );
-  /* ------------------------------------------------------------------------ **
-   * Initialize a tree node.
-   *
-   *  Input:   NodePtr  - a pointer to a ubi_btNode structure to be
-   *                      initialized.
-   *  Output:  a pointer to the initialized ubi_avlNode structure (ie. the
-   *           same as the input pointer).
-   * ------------------------------------------------------------------------ **
-   */
-
-ubi_trBool ubi_avlInsert( ubi_btRootPtr   RootPtr,
-                          ubi_avlNodePtr  NewNode,
-                          ubi_btItemPtr   ItemPtr,
-                          ubi_avlNodePtr *OldNode );
+ubi_trBool ubi_avlInsert( ubi_btRootPtr  RootPtr,
+                          ubi_btNodePtr  NewNode,
+                          ubi_btItemPtr  ItemPtr,
+                          ubi_btNodePtr *OldNode );
   /* ------------------------------------------------------------------------ **
    * This function uses a non-recursive algorithm to add a new element to
    * the tree.
    *
    *  Input:   RootPtr  -  a pointer to the ubi_btRoot structure that indicates
    *                       the root of the tree to which NewNode is to be added.
-   *           NewNode  -  a pointer to an ubi_avlNode structure that is NOT
+   *           NewNode  -  a pointer to an ubi_btNode structure that is NOT
    *                       part of any tree.
    *           ItemPtr  -  A pointer to the sort key that is stored within
    *                       *NewNode.  ItemPtr MUST point to information stored
@@ -228,8 +187,8 @@ ubi_trBool ubi_avlInsert( ubi_btRootPtr   RootPtr,
    * ------------------------------------------------------------------------ **
    */
 
-ubi_avlNodePtr ubi_avlRemove( ubi_btRootPtr  RootPtr,
-                              ubi_avlNodePtr DeadNode );
+ubi_btNodePtr ubi_avlRemove( ubi_btRootPtr RootPtr,
+                             ubi_btNodePtr DeadNode );
   /* ------------------------------------------------------------------------ **
    * This function removes the indicated node from the tree, after which the
    * tree is rebalanced.
@@ -273,60 +232,14 @@ int ubi_avlModuleID( int size, char *list[] );
  * type by including the appropriate module header.
  */
 
-#undef ubi_trNode
-#undef ubi_trNodePtr
-#define ubi_trNode    ubi_avlNode
-#define ubi_trNodePtr ubi_avlNodePtr
-
-#undef ubi_trInitNode
-#define ubi_trInitNode( Np ) ubi_avlInitNode( (ubi_avlNodePtr)(Np) )
-
 #undef ubi_trInsert
 #define ubi_trInsert( Rp, Nn, Ip, On ) \
-        ubi_avlInsert( (ubi_btRootPtr)(Rp), (ubi_avlNodePtr)(Nn), \
-                       (ubi_btItemPtr)(Ip), (ubi_avlNodePtr *)(On) )
+        ubi_avlInsert( (ubi_btRootPtr)(Rp), (ubi_btNodePtr)(Nn), \
+                       (ubi_btItemPtr)(Ip), (ubi_btNodePtr *)(On) )
 
 #undef ubi_trRemove
 #define ubi_trRemove( Rp, Dn ) \
-        ubi_avlRemove( (ubi_btRootPtr)(Rp), (ubi_avlNodePtr)(Dn) )
-
-#undef ubi_trLocate
-#define ubi_trLocate( Rp, Ip, Op ) \
-        (ubi_avlNodePtr)ubi_btLocate( (ubi_btRootPtr)(Rp), \
-                                      (ubi_btItemPtr)(Ip), \
-                                      (ubi_trCompOps)(Op) )
-
-#undef ubi_trFind
-#define ubi_trFind( Rp, Ip ) \
-        (ubi_avlNodePtr)ubi_btFind( (ubi_btRootPtr)(Rp), (ubi_btItemPtr)(Ip) )
-
-#undef ubi_trNext
-#define ubi_trNext( P ) (ubi_avlNodePtr)ubi_btNext( (ubi_btNodePtr)(P) )
-
-#undef ubi_trPrev
-#define ubi_trPrev( P ) (ubi_avlNodePtr)ubi_btPrev( (ubi_btNodePtr)(P) )
-
-#undef ubi_trFirst
-#define ubi_trFirst( P ) (ubi_avlNodePtr)ubi_btFirst( (ubi_btNodePtr)(P) )
-
-#undef ubi_trLast
-#define ubi_trLast( P ) (ubi_avlNodePtr)ubi_btLast( (ubi_btNodePtr)(P) )
-
-#undef ubi_trFirstOf
-#define ubi_trFirstOf( Rp, Ip, P ) \
-        (ubi_avlNodePtr)ubi_btFirstOf( (ubi_btRootPtr)(Rp), \
-                       (ubi_btItemPtr)(Ip), \
-                       (ubi_btNodePtr)(P) )
-
-#undef ubi_trLastOf
-#define ubi_trLastOf( Rp, Ip, P ) \
-        (ubi_avlNodePtr)ubi_btLastOf( (ubi_btRootPtr)(Rp), \
-                                      (ubi_btItemPtr)(Ip), \
-                                      (ubi_btNodePtr)(P) )
-
-#undef ubi_trLeafNode
-#define ubi_trLeafNode( Nd ) \
-        (ubi_avlNodePtr)ubi_btLeafNode( (ubi_btNodePtr)(Nd) )
+        ubi_avlRemove( (ubi_btRootPtr)(Rp), (ubi_btNodePtr)(Dn) )
 
 #undef ubi_trModuleID
 #define ubi_trModuleID( s, l ) ubi_avlModuleID( s, l )
index 501f3eeca79812c435f86cdf03e7f73e7a8b4e6a..c0f527e2d7c3f7761150b74eafd275e466389166 100644 (file)
@@ -1,7 +1,7 @@
 /* ========================================================================== **
  *                              ubi_BinTree.c
  *
- *  Copyright (C) 1991-1997 by Christopher R. Hertel
+ *  Copyright (C) 1991-1998 by Christopher R. Hertel
  *
  *  Email:  crh@ubiqx.mn.org
  * -------------------------------------------------------------------------- **
  * -------------------------------------------------------------------------- **
  *
  * Log: ubi_BinTree.c,v
+ * Revision 4.0  1998/03/10 03:19:22  crh
+ * Added the AVL field 'balance' to the ubi_btNode structure.  This means
+ * that all BinTree modules now use the same basic node structure, which
+ * greatly simplifies the AVL module.
+ * Decided that this was a big enough change to justify a new major revision
+ * number.  3.0 was an error, so we're at 4.0.
+ *
+ * Revision 2.6  1998/01/24 06:27:46  crh
+ * Added ubi_trCount() macro.
+ *
  * 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
  *
  * 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".
+ * For example, if you were using ubi_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
  */
 
 static char ModuleID[] = "ubi_BinTree\n\
-\tRevision: 2.5\n\
-\tDate: 1997/12/23 03:56:29\n\
+\tRevision: 4.0\n\
+\tDate: 1998/03/10 03:19:22\n\
 \tAuthor: crh\n";
 
 /* ========================================================================== **
@@ -209,7 +218,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,7 +236,7 @@ static void ReplaceNode( ubi_btNodePtr *parent,
    *           that now reads:
    *     ((unsigned char *)newnode)[i] = ((unsigned char *)oldnode)[i];
    *           Bleah!
-   * ------------------------------------------------------------------ *
+   * ------------------------------------------------------------------------ **
    */
   {
   register int i;
@@ -456,6 +465,7 @@ ubi_btNodePtr ubi_btInitNode( ubi_btNodePtr NodePtr )
   NodePtr->Link[ ubi_trPARENT ] = NULL;
   NodePtr->Link[ ubi_trRIGHT ]  = NULL;
   NodePtr->gender               = ubi_trEQUAL;
+  NodePtr->balance              = ubi_trEQUAL;
   return( NodePtr );
   } /* ubi_btInitNode */
 
index 4b918a46096c7379c3ab7d732a64d5e751ad844d..f3c49c95e1bbd9e1c598aaa6683feac190974b3a 100644 (file)
@@ -3,7 +3,7 @@
 /* ========================================================================== **
  *                              ubi_BinTree.h
  *
- *  Copyright (C) 1991-1997 by Christopher R. Hertel
+ *  Copyright (C) 1991-1998 by Christopher R. Hertel
  *
  *  Email:  crh@ubiqx.mn.org
  * -------------------------------------------------------------------------- **
  * -------------------------------------------------------------------------- **
  *
  * Log: ubi_BinTree.h,v
+ * Revision 4.0  1998/03/10 03:16:04  crh
+ * Added the AVL field 'balance' to the ubi_btNode structure.  This means
+ * that all BinTree modules now use the same basic node structure, which
+ * greatly simplifies the AVL module.
+ * Decided that this was a big enough change to justify a new major revision
+ * number.  3.0 was an error, so we're at 4.0.
+ *
+ * Revision 2.6  1998/01/24 06:27:30  crh
+ * Added ubi_trCount() macro.
+ *
  * 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
  *
  * 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".
+ * For example, if you were using ubi_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
@@ -197,6 +206,16 @@ typedef enum {
 #define ubi_trOvwt_OK(A) \
         ((ubi_trOVERWRITE & ((A)->flags))?(ubi_trTRUE):(ubi_trFALSE))
 
+/* -------------------------------------------------------------------------- **
+ * A quickie for consistency.
+ *  ubi_trCount() - Given a pointer to a tree root, this macro returns the
+ *                  number of nodes currently in the tree.
+ *
+ * -------------------------------------------------------------------------- **
+ */
+
+#define ubi_trCount( R ) (((ubi_trRootPtr)(R))->count)
+
 /* -------------------------------------------------------------------------- **
  * Typedefs...
  * 
@@ -211,7 +230,7 @@ typedef enum {
 
 typedef unsigned char ubi_trBool;
 
-typedef void *ubi_btItemPtr;              /* A pointer to data within a node. */
+typedef void *ubi_btItemPtr;          /* A pointer to key data within a node. */
 
 /*  ------------------------------------------------------------------------- **
  *  Binary Tree Node Structure:  This structure defines the basic elements of
@@ -230,11 +249,16 @@ typedef void *ubi_btItemPtr;              /* A pointer to 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.
+ *    balance  -  only used by the AVL tree module.  This field indicates
+ *                the height balance at a given node.  See ubi_AVLtree for
+ *                details.
+ *
  *  ------------------------------------------------------------------------- **
  */
 typedef struct ubi_btNodeStruct {
   struct ubi_btNodeStruct *Link[ 3 ];
-  char                     gender;
+  signed char              gender;
+  signed char              balance;
   } ubi_btNode;
 
 typedef ubi_btNode *ubi_btNodePtr;     /* Pointer to an ubi_btNode structure. */
@@ -272,8 +296,8 @@ typedef void (*ubi_btKillNodeRtn)( ubi_btNodePtr );
 
 /* -------------------------------------------------------------------------- **
  * 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.
+ *                      accessing whole binary trees.  The fields are:
+ *    root  -  A pointer to the root node of the 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
  *             searching the tree.
@@ -294,8 +318,8 @@ typedef void (*ubi_btKillNodeRtn)( ubi_btNodePtr );
 
 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  */
+  unsigned long  count;    /* A count of the number of nodes in the tree   */
   unsigned char  flags;    /* Overwrite Y|N, Duplicate keys Y|N...         */
   } ubi_btRoot;
 
index 799996b6cc3739c00cca54e1ce2a3409bc14040d..89ddfb988ac0d547fe2023ae4bd1814d33ab7915 100644 (file)
@@ -1,7 +1,7 @@
 /* ========================================================================== **
  *                              ubi_SplayTree.c
  *
- *  Copyright (C) 1993-1995 by Christopher R. Hertel
+ *  Copyright (C) 1993-1998 by Christopher R. Hertel
  *
  *  Email: crh@ubiqx.mn.org
  * -------------------------------------------------------------------------- **
@@ -16,6 +16,8 @@
  *              Robert Tarjan.  Journal of the Association for Computing
  *              Machinery Vol 32, No. 3, July 1985 pp. 652-686
  *
+ *    See also: http://www.cs.cmu.edu/~sleator/
+ *
  * -------------------------------------------------------------------------- **
  *
  *  This library is free software; you can redistribute it and/or
  * -------------------------------------------------------------------------- **
  *
  * Log: ubi_SplayTree.c,v
+ * Revision 4.0  1998/03/10 03:41:33  crh
+ * Minor comment changes.  The revision number is now 4.0 to match the
+ * BinTree and AVLtree modules.
+ *
+ * Revision 2.7  1998/01/24 06:37:08  crh
+ * Added a URL for more information.
+ *
  * 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
  *
  * 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".
+ * For example, if you were using ubi_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
  */
 
 static char ModuleID[] = "ubi_SplayTree\n\
-\tRevision: 2.6\n\
-\tDate: 1997/12/23 04:01:12\n\
+\tRevision: 4.0\n\
+\tDate: 1998/03/10 03:41:33\n\
 \tAuthor: crh\n";
 
 
@@ -466,3 +474,4 @@ int ubi_sptModuleID( int size, char *list[] )
   } /* ubi_sptModuleID */
 
 /* ================================ The End ================================= */
+
index d45c32fce83d9858ca2a72ad2d4bcaaf335b278e..9e557347020fec8f08f8c9e6691fab9d76425de7 100644 (file)
@@ -3,7 +3,7 @@
 /* ========================================================================== **
  *                              ubi_SplayTree.h
  *
- *  Copyright (C) 1993,1995 by Christopher R. Hertel
+ *  Copyright (C) 1993-1998 by Christopher R. Hertel
  *
  *  Email: crh@ubiqx.mn.org
  * -------------------------------------------------------------------------- **
@@ -18,6 +18,8 @@
  *              Robert Tarjan.  Journal of the Association for Computing
  *              Machinery Vol 32, No. 3, July 1985 pp. 652-686
  *
+ *    See also: http://www.cs.cmu.edu/~sleator/ 
+ *
  * -------------------------------------------------------------------------- **
  *
  *  This library is free software; you can redistribute it and/or
  * -------------------------------------------------------------------------- **
  *
  * Log: ubi_SplayTree.h,v
+ * Revision 4.0  1998/03/10 03:40:57  crh
+ * Minor comment changes.  The revision number is now 4.0 to match the
+ * BinTree and AVLtree modules.
+ *
+ * Revision 2.7  1998/01/24 06:37:57  crh
+ * Added a URL for more information.
+ *
  * 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
  *
  * 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".
+ * For example, if you were using ubi_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
@@ -328,8 +336,3 @@ int ubi_sptModuleID( int size, char *list[] );
 
 /* ================================ The End ================================= */
 #endif /* ubi_SplayTree_H */
-
-
-
-
-
index 5d970a9ca1388db017ffc797eb747a5b08b060d4..c903dcbc042a8813559684b8f64a3246210ce870 100644 (file)
@@ -1,7 +1,7 @@
 /* ========================================================================== **
  *                              ubi_dLinkList.c
  *
- *  Copyright (C) 1997 by Christopher R. Hertel
+ *  Copyright (C) 1997, 1998 by Christopher R. Hertel
  *
  *  Email: crh@ubiqx.mn.org
  * -------------------------------------------------------------------------- **
  *
  * -------------------------------------------------------------------------- **
  *
+ * Log: ubi_dLinkList.c,v
+ * Revision 0.5  1998/03/10 02:55:00  crh
+ * Simplified the code and added macros for stack & queue manipulations.
+ *
+ * Revision 0.4  1998/01/03 01:53:56  crh
+ * Added ubi_dlCount() macro.
+ *
  * Revision 0.3  1997/10/15 03:05:39  crh
  * Added some handy type casting to the macros.  Added AddHere and RemThis
  * macros.
  * Revision 0.1  1997/10/07 04:34:07  crh
  * Initial Revision.
  *
+ * -------------------------------------------------------------------------- **
+ * This module is similar to the ubi_sLinkList module, but it is neither a
+ * descendant type nor an easy drop-in replacement for the latter.  One key
+ * difference is that the ubi_dlRemove() function removes the indicated node,
+ * while the ubi_slRemove() function (in ubi_sLinkList) removes the node
+ * *following* the indicated node.
  *
  * ========================================================================== **
  */
 
-#include "../includes.h"
 #include "ubi_dLinkList.h"
 
 /* ========================================================================== **
@@ -85,28 +97,17 @@ ubi_dlNodePtr ubi_dlInsert( ubi_dlListPtr ListPtr,
    * ------------------------------------------------------------------------ **
    */
   {
-  if( NULL == After )
-    {
-    New->Next           = ListPtr->Head;
-    New->Prev           = NULL;
-    if( NULL != ListPtr->Head )
-      ListPtr->Head->Prev = New;
-    else
-      ListPtr->Tail       = New;
-    ListPtr->Head       = New;
-    }
+  ubi_dlNodePtr PredNode = After ? After : (ubi_dlNodePtr)ListPtr;
+
+  New->Next         = PredNode->Next;
+  New->Prev         = After;
+  PredNode->Next    = New;
+  if( New->Next )
+    New->Next->Prev = New;
   else
-    {
-    New->Next         = After->Next;
-    New->Prev         = After;
-    if( NULL != After->Next )
-      After->Next->Prev = New;
-    else
-      ListPtr->Tail       = New;
-    After->Next       = New;
-    }
+    ListPtr->Tail   = New;
 
-  ++(ListPtr->count);
+  (ListPtr->count)++;
 
   return( New );
   } /* ubi_dlInsert */
@@ -125,7 +126,7 @@ ubi_dlNodePtr ubi_dlRemove( ubi_dlListPtr ListPtr, ubi_dlNodePtr Old )
    * ------------------------------------------------------------------------ **
    */
   {
-  if( NULL != Old )
+  if( Old )
     {
     if( Old->Next )
       Old->Next->Prev = Old->Prev;
@@ -137,11 +138,10 @@ ubi_dlNodePtr ubi_dlRemove( ubi_dlListPtr ListPtr, ubi_dlNodePtr Old )
     else
       ListPtr->Head = Old->Next;
 
-    --(ListPtr->count);
+    (ListPtr->count)--;
     }
 
   return( Old );
   } /* ubi_dlRemove */
 
-
 /* ================================ The End ================================= */
index 1facf92d3b1c1843cb66874943b1d03679e24edc..9c6a3be2e2adb5c5bdac588a6bf6378ab88a9ce9 100644 (file)
@@ -3,7 +3,7 @@
 /* ========================================================================== **
  *                              ubi_dLinkList.h
  *
- *  Copyright (C) 1997 by Christopher R. Hertel
+ *  Copyright (C) 1997, 1998 by Christopher R. Hertel
  *
  *  Email: crh@ubiqx.mn.org
  * -------------------------------------------------------------------------- **
  *
  * -------------------------------------------------------------------------- **
  *
+ * Log: ubi_dLinkList.h,v
+ * Revision 0.5  1998/03/10 02:54:04  crh
+ * Simplified the code and added macros for stack & queue manipulations.
+ *
+ * Revision 0.4  1998/01/03 01:53:44  crh
+ * Added ubi_dlCount() macro.
+ *
  * Revision 0.3  1997/10/15 03:04:31  crh
  * Added some handy type casting to the macros.  Added AddHere and RemThis
  * macros.
  * Revision 0.1  1997/10/07 04:34:38  crh
  * Initial Revision.
  *
+ * -------------------------------------------------------------------------- **
+ * This module is similar to the ubi_sLinkList module, but it is neither a
+ * descendant type nor an easy drop-in replacement for the latter.  One key
+ * difference is that the ubi_dlRemove() function removes the indicated node,
+ * while the ubi_slRemove() function (in ubi_sLinkList) removes the node
+ * *following* the indicated node.
  *
  * ========================================================================== **
  */
@@ -73,46 +86,63 @@ typedef ubi_dlList *ubi_dlListPtr;
 
 /* ========================================================================== **
  * Macros...
- * 
+ *
+ *  ubi_dlCount   - Return the number of entries currently in the list.
+ *
  *  ubi_dlAddHead - Add a new node at the head of the list.
+ *  ubi_dlAddNext - Add a node following the given node.
  *  ubi_dlAddTail - Add a new node at the tail of the list.
- *  ubi_dlAddHere - Add a node following the given node.
+ *                  Note: AddTail evaluates the L parameter twice.
+ *
  *  ubi_dlRemHead - Remove the node at the head of the list, if any.
- *  ubi_dlRemTail - Remove the node at the tail of the list, if any.
+ *                  Note: RemHead evaluates the L parameter twice.
  *  ubi_dlRemThis - Remove the indicated node.
+ *  ubi_dlRemTail - Remove the node at the tail of the list, if any.
+ *                  Note: RemTail evaluates the L parameter twice.
+ *
  *  ubi_dlFirst   - Return a pointer to the first node in the list, if any.
  *  ubi_dlLast    - Return a pointer to the last node in the list, if any.
  *  ubi_dlNext    - Given a node, return a pointer to the next node.
  *  ubi_dlPrev    - Given a node, return a pointer to the previous node.
  *
+ *  ubi_dlPush    - Add a node at the head of the list (synonym of AddHead).
+ *  ubi_dlPop     - Remove a node at the head of the list (synonym of RemHead).
+ *  ubi_dlEnqueue - Add a node at the tail of the list (sysnonym of AddTail).
+ *  ubi_dlDequeue - Remove a node at the head of the list (synonym of RemHead).
+ *
  *  Note that all of these provide type casting of the parameters.  The
  *  Add and Rem macros are nothing more than nice front-ends to the
  *  Insert and Remove operations.
  *
+ *  Also note that there the First, Next and Last macros do no parameter
+ *  checking!
+ *
  */
 
+#define ubi_dlCount( L ) (((ubi_dlListPtr)(L))->count)
+
 #define ubi_dlAddHead( L, N ) \
         ubi_dlInsert( (ubi_dlListPtr)(L), (ubi_dlNodePtr)(N), NULL )
 
-#define ubi_dlAddTail( L, N ) \
+#define ubi_dlAddNext( L, N, A ) \
         ubi_dlInsert( (ubi_dlListPtr)(L), \
                       (ubi_dlNodePtr)(N), \
-                    (((ubi_dlListPtr)(L))->Tail) )
+                      (ubi_dlNodePtr)(A) )
 
-#define ubi_dlAddHere( L, N, P ) \
+#define ubi_dlAddTail( L, N ) \
         ubi_dlInsert( (ubi_dlListPtr)(L), \
                       (ubi_dlNodePtr)(N), \
-                      (ubi_dlNodePtr)(P) )
+                    (((ubi_dlListPtr)(L))->Tail) )
 
 #define ubi_dlRemHead( L ) ubi_dlRemove( (ubi_dlListPtr)(L), \
                                          (((ubi_dlListPtr)(L))->Head) )
 
-#define ubi_dlRemTail( L ) ubi_dlRemove( (ubi_dlListPtr)(L), \
-                                         (((ubi_dlListPtr)(L))->Tail) )
-
 #define ubi_dlRemThis( L, N ) ubi_dlRemove( (ubi_dlListPtr)(L), \
                                             (ubi_dlNodePtr)(N) )
 
+#define ubi_dlRemTail( L ) ubi_dlRemove( (ubi_dlListPtr)(L), \
+                                         (((ubi_dlListPtr)(L))->Tail) )
+
 #define ubi_dlFirst( L ) (((ubi_dlListPtr)(L))->Head)
 
 #define ubi_dlLast( L )  (((ubi_dlListPtr)(L))->Tail)
@@ -121,6 +151,10 @@ typedef ubi_dlList *ubi_dlListPtr;
 
 #define ubi_dlPrev( N )  (((ubi_dlNodePtr)(N))->Prev)
 
+#define ubi_dlPush    ubi_dlAddHead
+#define ubi_dlPop     ubi_dlRemHead
+#define ubi_dlEnqueue ubi_dlAddTail
+#define ubi_dlDequeue ubi_dlRemHead
 
 /* ========================================================================== **
  * Function prototypes...
@@ -173,6 +207,5 @@ ubi_dlNodePtr ubi_dlRemove( ubi_dlListPtr ListPtr, ubi_dlNodePtr Old );
    * ------------------------------------------------------------------------ **
    */
 
-
 /* ================================ The End ================================= */
 #endif /* ubi_dLinkList_H */
index 5414d5f71de927e7ef03d553d5f6ee551e039975..3dc4f0640cb14cf555cf4404f6dbce47626f0239 100644 (file)
@@ -1,11 +1,11 @@
 /* ========================================================================== **
  *                              ubi_sLinkList.c
  *
- *  Copyright (C) 1997 by Christopher R. Hertel
+ *  Copyright (C) 1997, 1998 by Christopher R. Hertel
  *
  *  Email: crh@ubiqx.mn.org
  * -------------------------------------------------------------------------- **
- *  This module implements a really simple singly-linked list.
+ *  This module implements a simple singly-linked list.
  * -------------------------------------------------------------------------- **
  *
  *  This library is free software; you can redistribute it and/or
  *
  * -------------------------------------------------------------------------- **
  *
+ * Log: ubi_sLinkList.c,v
+ * Revision 0.4  1998/03/10 02:23:20  crh
+ * Combined ubi_StackQueue and ubi_sLinkList into one module.  Redesigned
+ * the functions and macros.  Not a complete rewrite but close to it.
+ *
+ * Revision 0.3  1998/01/03 01:59:52  crh
+ * Added ubi_slCount() macro.
+ *
  * Revision 0.2  1997/10/21 03:35:18  crh
  * Added parameter <After> in function Insert().  Made necessary changes
  * to macro AddHead() and added macro AddHere().
  * Revision 0.1  1997/10/16 02:53:45  crh
  * Initial Revision.
  *
+ * -------------------------------------------------------------------------- **
+ *  This module implements a singly-linked list which may also be used as a
+ *  queue or a stack.  For a queue, entries are added at the tail and removed
+ *  from the head of the list.  For a stack, the entries are entered and
+ *  removed from the head of the list.  A traversal of the list will always
+ *  start at the head of the list and proceed toward the tail.  This is all
+ *  mind-numbingly simple, but I'm surprised by the number of programs out
+ *  there which re-implement this a dozen or so times.
+ *
+ *  Notes:  When the list header is initialized, the Tail pointer is set to
+ *          point to the Head pointer.  This simplifies things a great deal,
+ *          except that you can't initialize a stack or queue by simply
+ *          zeroing it out.  One sure way to initialize the header is to call
+ *          ubi_slInit().  Another option would be something like this:
+ *
+ *          static ubi_slList MyList = { NULL, (ubi_slNodePtr)&MyList, 0 };
+ *
+ *          See ubi_slInit() and the ubi_slList structure for more info.
+ *
+ *        + Also, note that this module is similar to the ubi_dLinkList
+ *          module.  There are three key differences:
+ *          - This is a singly-linked list, the other is a doubly-linked
+ *            list.
+ *          - In this module, if the list is empty, the tail pointer will
+ *            point back to the head of the list as described above.  This
+ *            is not done in ubi_dLinkList.
+ *          - The ubi_slRemove() function, by necessity, removed the 'next'
+ *            node.  In ubi_dLinkList, the ubi_dlRemove() function removes
+ *            the 'current' node.
+ *
  * ========================================================================== **
  */
 
@@ -54,6 +92,7 @@ ubi_slListPtr ubi_slInitList( ubi_slListPtr ListPtr )
    */
   {
   ListPtr->Head  = NULL;
+  ListPtr->Tail  = (ubi_slNodePtr)ListPtr;
   ListPtr->count = 0;
   return( ListPtr );
   } /* ubi_slInitList */
@@ -62,7 +101,7 @@ ubi_slNodePtr ubi_slInsert( ubi_slListPtr ListPtr,
                             ubi_slNodePtr New,
                             ubi_slNodePtr After )
   /* ------------------------------------------------------------------------ **
-   * Insert a new node at the head of the list.
+   * Add a node to the list.
    *
    *  Input:  ListPtr - A pointer to the list into which the node is to
    *                    be inserted.
@@ -77,36 +116,43 @@ ubi_slNodePtr ubi_slInsert( ubi_slListPtr ListPtr,
    * ------------------------------------------------------------------------ **
    */
   {
-  ubi_slNodePtr *PredPtr;
-
-  PredPtr = ( NULL == After ) ? &(ListPtr->Head) : &(After->Next);
-  New->Next = *PredPtr;
-  *PredPtr  = New;
-  ++(ListPtr->count);
+  After = After ? After : (ubi_slNodePtr)ListPtr;
+  New->Next   = After->Next;
+  After->Next = New;
+  if( !(New->Next) )
+    ListPtr->Tail = New;
+  (ListPtr->count)++;
   return( New );
   } /* ubi_slInsert */
 
-ubi_slNodePtr ubi_slRemove( ubi_slListPtr ListPtr )
+ubi_slNodePtr ubi_slRemove( ubi_slListPtr ListPtr, ubi_slNodePtr After )
   /* ------------------------------------------------------------------------ **
-   * Remove a node from the head of the list.
+   * Remove the node followng <After>.  If <After> is NULL, remove from the
+   * head of the list.
    *
    *  Input:  ListPtr - A pointer to the list from which the node is to be
    *                    removed.
+   *          After   - Pointer to the node preceeding the node to be
+   *                    removed.
    *
-   *  Output: A pointer to the node that was removed.
+   *  Output: A pointer to the node that was removed, or NULL if the list is
+   *          empty.
    *
    * ------------------------------------------------------------------------ **
    */
   {
-  ubi_slNodePtr Old = ListPtr->Head;
+  ubi_slNodePtr DelNode;
 
-  if( NULL != Old )
+  After   = After ? After : (ubi_slNodePtr)ListPtr;
+  DelNode = After->Next;
+  if( DelNode )
     {
-    ListPtr->Head = Old->Next;
-    --(ListPtr->count);
+    if( !(DelNode->Next) )
+      ListPtr->Tail = After;
+    After->Next  = DelNode->Next;
+    (ListPtr->count)--;
     }
-  return( Old );
+  return( DelNode );
   } /* ubi_slRemove */
 
-
 /* ================================ The End ================================= */
index 7d546f06e95f26a30d3fb4d1bd886168c6a54569..2275d852da1c26715a4040443257d4528139ea78 100644 (file)
@@ -3,11 +3,11 @@
 /* ========================================================================== **
  *                              ubi_sLinkList.h
  *
- *  Copyright (C) 1997 by Christopher R. Hertel
+ *  Copyright (C) 1997, 1998 by Christopher R. Hertel
  *
  *  Email: crh@ubiqx.mn.org
  * -------------------------------------------------------------------------- **
- *  This module implements a really simple singly-linked list.
+ *  This module implements a simple singly-linked list.
  * -------------------------------------------------------------------------- **
  *
  *  This library is free software; you can redistribute it and/or
  *
  * -------------------------------------------------------------------------- **
  *
+ * Log: ubi_sLinkList.h,v
+ * Revision 0.4  1998/03/10 02:22:39  crh
+ * Combined ubi_StackQueue and ubi_sLinkList into one module.  Redesigned
+ * the functions and macros.  Not a complete rewrite but close to it.
+ *
+ * Revision 0.3  1998/01/03 02:00:02  crh
+ * Added ubi_slCount() macro.
+ *
  * Revision 0.2  1997/10/21 03:36:14  crh
  * Added parameter <After> in function Insert().  Made necessary changes
  * to macro AddHead() and added macro AddHere().
  * Revision 0.1  1997/10/16 02:54:08  crh
  * Initial Revision.
  *
+ * -------------------------------------------------------------------------- **
+ *  This module implements a singly-linked list which may also be used as a 
+ *  queue or a stack.  For a queue, entries are added at the tail and removed
+ *  from the head of the list.  For a stack, the entries are entered and
+ *  removed from the head of the list.  A traversal of the list will always
+ *  start at the head of the list and proceed toward the tail.  This is all
+ *  mind-numbingly simple, but I'm surprised by the number of programs out
+ *  there which re-implement this a dozen or so times.
+ *
+ *  Note:  When the list header is initialized, the Tail pointer is set to
+ *         point to the Head pointer.  This simplifies things a great deal,
+ *         except that you can't initialize a stack or queue by simply
+ *         zeroing it out.  One sure way to initialize the header is to call
+ *         ubi_slInit().  Another option would be something like this:
+ *
+ *         static ubi_slList MyList = { NULL, (ubi_slNodePtr)&MyList, 0 };
+ *
+ *         See ubi_slInit() and the ubi_slList structure for more info.
+ *
+ *        + Also, note that this module is similar to the ubi_dLinkList
+ *          module.  There are three key differences:
+ *          - This is a singly-linked list, the other is a doubly-linked
+ *            list.
+ *          - In this module, if the list is empty, the tail pointer will
+ *            point back to the head of the list as described above.  This
+ *            is not done in ubi_dLinkList.
+ *          - The ubi_slRemove() function, by necessity, removed the 'next'
+ *            node.  In ubi_dLinkList, the ubi_dlRemove() function removes
+ *            the 'current' node. 
+ *
  * ========================================================================== **
  */
 
@@ -59,6 +97,7 @@ typedef ubi_slNode *ubi_slNodePtr;
 typedef struct
   {
   ubi_slNodePtr Head;
+  ubi_slNodePtr Tail;
   unsigned long count;
   } ubi_slList;
 
@@ -67,31 +106,64 @@ typedef ubi_slList *ubi_slListPtr;
 /* ========================================================================== **
  * Macros...
  * 
+ *  ubi_slCount   - Returns the current number of entries in the list.
+ *
  *  ubi_slAddHead - Add a new node at the head of the list.
+ *  ubi_slAddNext - Add a new node following the indicated node.
+ *  ubi_slAddTail - Add a new node to the tail of the list.
+ *                  Note: AddTail evaluates the L parameter twice.
+ *
  *  ubi_slRemHead - Remove the node at the head of the list, if any.
+ *  ubi_slRemNext - Remove the node following the given node.
+ *
  *  ubi_slFirst   - Return a pointer to the first node in the list, if any.
  *  ubi_slNext    - Given a node, return a pointer to the next node.
+ *  ubi_slLast    - Return a pointer to the last node in the list, if any.
+ *
+ *  ubi_slPush    - Add a node at the head of the list (synonym of AddHead).
+ *  ubi_slPop     - Remove a node at the head of the list (synonym of RemHead).
+ *  ubi_slEnqueue - Add a node at the tail of the list (sysnonym of AddTail).
+ *  ubi_slDequeue - Remove a node at the head of the list (synonym of RemHead).
  *
  *  Note that all of these provide type casting of the parameters.  The
  *  Add and Rem macros are nothing more than nice front-ends to the
- *  Insert and Remove operations.
+ *  Insert and Remove functions.
+ *
+ *  Also note that there the First, Next and Last macros do no parameter
+ *  checking!
  *
  */
 
+#define ubi_slCount( L ) (((ubi_slListPtr)(L))->count)
+
 #define ubi_slAddHead( L, N ) \
         ubi_slInsert( (ubi_slListPtr)(L), (ubi_slNodePtr)(N), NULL )
 
-#define ubi_slAddHere( L, N, P ) \
+#define ubi_slAddNext( L, N, A ) \
+        ubi_slInsert( (ubi_slListPtr)(L), \
+                      (ubi_slNodePtr)(N), \
+                      (ubi_slNodePtr)(A) )
+
+#define ubi_slAddTail( L, N ) \
         ubi_slInsert( (ubi_slListPtr)(L), \
                       (ubi_slNodePtr)(N), \
-                      (ubi_slNodePtr)(P) )
+                     ((ubi_slListPtr)(L))->Tail )
+
+#define ubi_slRemHead( L ) ubi_slRemove( (ubi_slListPtr)(L), NULL )
 
-#define ubi_slRemHead( L ) ubi_slRemove( (ubi_slListPtr)(L) )
+#define ubi_slRemNext( L, N ) \
+        ubi_slRemove( (ubi_slListPtr)(L), (ubi_slNodePtr)(N) )
 
 #define ubi_slFirst( L ) (((ubi_slListPtr)(L))->Head)
 
 #define ubi_slNext( N )  (((ubi_slNodePtr)(N))->Next)
 
+#define ubi_slLast( L )  (((ubi_slListPtr)(L))->Tail)
+
+#define ubi_slPush    ubi_slAddHead
+#define ubi_slPop     ubi_slRemHead
+#define ubi_slEnqueue ubi_slAddTail
+#define ubi_slDequeue ubi_slRemHead
 
 /* ========================================================================== **
  * Function prototypes...
@@ -114,7 +186,7 @@ ubi_slNodePtr ubi_slInsert( ubi_slListPtr ListPtr,
                             ubi_slNodePtr New,
                             ubi_slNodePtr After );
   /* ------------------------------------------------------------------------ **
-   * Insert a new node at the head of the list.
+   * Add a node to the list.
    *
    *  Input:  ListPtr - A pointer to the list into which the node is to
    *                    be inserted.
@@ -129,14 +201,18 @@ ubi_slNodePtr ubi_slInsert( ubi_slListPtr ListPtr,
    * ------------------------------------------------------------------------ **
    */
 
-ubi_slNodePtr ubi_slRemove( ubi_slListPtr ListPtr );
+ubi_slNodePtr ubi_slRemove( ubi_slListPtr ListPtr, ubi_slNodePtr After );
   /* ------------------------------------------------------------------------ **
-   * Remove a node from the head of the list.
+   * Remove the node followng <After>.  If <After> is NULL, remove from the
+   * head of the list.
    *
    *  Input:  ListPtr - A pointer to the list from which the node is to be
    *                    removed.
+   *          After   - Pointer to the node preceeding the node to be
+   *                    removed.
    *
-   *  Output: A pointer to the node that was removed.
+   *  Output: A pointer to the node that was removed, or NULL if the list is
+   *          empty.
    *
    * ------------------------------------------------------------------------ **
    */