mirror of
https://github.com/samba-team/samba.git
synced 2025-01-26 10:04:02 +03:00
Updates to all of these base level modules.
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 commit is contained in:
parent
8e4a412dba
commit
599a29401d
@ -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
|
||||
* -------------------------------------------------------------------------- **
|
||||
@ -32,6 +32,14 @@
|
||||
* -------------------------------------------------------------------------- **
|
||||
*
|
||||
* 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
|
||||
@ -92,10 +100,9 @@
|
||||
*
|
||||
* 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
|
||||
@ -129,8 +136,8 @@
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
|
@ -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
|
||||
* -------------------------------------------------------------------------- **
|
||||
@ -35,6 +35,14 @@
|
||||
*
|
||||
* -------------------------------------------------------------------------- **
|
||||
* 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
|
||||
@ -95,10 +103,9 @@
|
||||
*
|
||||
* 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
|
||||
@ -126,70 +133,22 @@
|
||||
|
||||
#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 )
|
||||
|
@ -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
|
||||
* -------------------------------------------------------------------------- **
|
||||
@ -27,6 +27,16 @@
|
||||
* -------------------------------------------------------------------------- **
|
||||
*
|
||||
* 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
|
||||
@ -79,10 +89,9 @@
|
||||
*
|
||||
* 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
|
||||
@ -116,8 +125,8 @@
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
|
@ -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
|
||||
* -------------------------------------------------------------------------- **
|
||||
@ -29,6 +29,16 @@
|
||||
* -------------------------------------------------------------------------- **
|
||||
*
|
||||
* 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
|
||||
@ -81,10 +91,9 @@
|
||||
*
|
||||
* 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;
|
||||
|
||||
|
@ -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
|
||||
@ -35,6 +37,13 @@
|
||||
* -------------------------------------------------------------------------- **
|
||||
*
|
||||
* 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
|
||||
@ -80,10 +89,9 @@
|
||||
*
|
||||
* 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
|
||||
@ -123,8 +131,8 @@
|
||||
*/
|
||||
|
||||
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 ================================= */
|
||||
|
||||
|
@ -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
|
||||
@ -37,6 +39,13 @@
|
||||
* -------------------------------------------------------------------------- **
|
||||
*
|
||||
* 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
|
||||
@ -79,10 +88,9 @@
|
||||
*
|
||||
* 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 */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
* -------------------------------------------------------------------------- **
|
||||
@ -24,6 +24,13 @@
|
||||
*
|
||||
* -------------------------------------------------------------------------- **
|
||||
*
|
||||
* 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.
|
||||
@ -35,11 +42,16 @@
|
||||
* 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
New->Next = After->Next;
|
||||
New->Prev = After;
|
||||
if( NULL != After->Next )
|
||||
After->Next->Prev = New;
|
||||
else
|
||||
ListPtr->Tail = New;
|
||||
After->Next = New;
|
||||
}
|
||||
ubi_dlNodePtr PredNode = After ? After : (ubi_dlNodePtr)ListPtr;
|
||||
|
||||
++(ListPtr->count);
|
||||
New->Next = PredNode->Next;
|
||||
New->Prev = After;
|
||||
PredNode->Next = New;
|
||||
if( New->Next )
|
||||
New->Next->Prev = New;
|
||||
else
|
||||
ListPtr->Tail = New;
|
||||
|
||||
(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 ================================= */
|
||||
|
@ -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
|
||||
* -------------------------------------------------------------------------- **
|
||||
@ -26,6 +26,13 @@
|
||||
*
|
||||
* -------------------------------------------------------------------------- **
|
||||
*
|
||||
* 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.
|
||||
@ -37,6 +44,12 @@
|
||||
* 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_dlAddNext( L, N, A ) \
|
||||
ubi_dlInsert( (ubi_dlListPtr)(L), \
|
||||
(ubi_dlNodePtr)(N), \
|
||||
(ubi_dlNodePtr)(A) )
|
||||
|
||||
#define ubi_dlAddTail( L, N ) \
|
||||
ubi_dlInsert( (ubi_dlListPtr)(L), \
|
||||
(ubi_dlNodePtr)(N), \
|
||||
(((ubi_dlListPtr)(L))->Tail) )
|
||||
|
||||
#define ubi_dlAddHere( L, N, P ) \
|
||||
ubi_dlInsert( (ubi_dlListPtr)(L), \
|
||||
(ubi_dlNodePtr)(N), \
|
||||
(ubi_dlNodePtr)(P) )
|
||||
|
||||
#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 */
|
||||
|
@ -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
|
||||
@ -24,6 +24,14 @@
|
||||
*
|
||||
* -------------------------------------------------------------------------- **
|
||||
*
|
||||
* 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().
|
||||
@ -31,6 +39,36 @@
|
||||
* 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 ================================= */
|
||||
|
@ -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
|
||||
@ -26,6 +26,14 @@
|
||||
*
|
||||
* -------------------------------------------------------------------------- **
|
||||
*
|
||||
* 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().
|
||||
@ -33,6 +41,36 @@
|
||||
* 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)(P) )
|
||||
(ubi_slNodePtr)(A) )
|
||||
|
||||
#define ubi_slRemHead( L ) ubi_slRemove( (ubi_slListPtr)(L) )
|
||||
#define ubi_slAddTail( L, N ) \
|
||||
ubi_slInsert( (ubi_slListPtr)(L), \
|
||||
(ubi_slNodePtr)(N), \
|
||||
((ubi_slListPtr)(L))->Tail )
|
||||
|
||||
#define ubi_slRemHead( L ) ubi_slRemove( (ubi_slListPtr)(L), NULL )
|
||||
|
||||
#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.
|
||||
*
|
||||
* ------------------------------------------------------------------------ **
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user