示例#1
0
文件: ubi_BinTree.c 项目: mbethke/hsc
static ubi_btNodePtr Neighbor( register ubi_btNodePtr P,
                               register int           whichway )
/* ------------------------------------------------------------------------ **
 * Given starting point p, return the (key order) next or preceeding node
 * in the tree.
 *
 *  Input:  P         - Pointer to our starting place node.
 *          whichway  - the direction in which to travel to find the
 *                      neighbor, i.e., the RIGHT neighbor or the LEFT
 *                      neighbor.
 *
 *  Output: A pointer to the neighboring node, or NULL if P was NULL.
 *
 *  Notes:  If whichway is PARENT, the results are unpredictable.
 * ------------------------------------------------------------------------ **
 */
{
    if( P )
    {
        if( NULL != P->Link[ whichway ] )
            return( SubSlide( P->Link[ whichway ], (char)ubi_trRevWay(whichway) ) );
        else
            while( NULL != P->Link[ ubi_trPARENT ] )
            {
                if( whichway == P->gender )
                    P = P->Link[ ubi_trPARENT ];
                else
                    return( P->Link[ ubi_trPARENT ] );
            }
    }
    return( NULL );
} /* Neighbor */
示例#2
0
ubi_btNodePtr ubi_btLeafNode( ubi_btNodePtr leader )
  /* ------------------------------------------------------------------------ **
   * Returns a pointer to a leaf node.
   *
   *  Input:  leader  - Pointer to a node at which to start the descent.
   *
   *  Output: A pointer to a leaf node selected in a somewhat arbitrary
   *          manner.
   *
   *  Notes:  I wrote this function because I was using splay trees as a
   *          database cache.  The cache had a maximum size on it, and I
   *          needed a way of choosing a node to sacrifice if the cache
   *          became full.  In a splay tree, less recently accessed nodes
   *          tend toward the bottom of the tree, meaning that leaf nodes
   *          are good candidates for removal.  (I really can't think of
   *          any other reason to use this function.)
   *        + In a simple binary tree or an AVL tree, the most recently
   *          added nodes tend to be nearer the bottom, making this a *bad*
   *          way to choose which node to remove from the cache.
   *        + Randomizing the traversal order is probably a good idea.  You
   *          can improve the randomization of leaf node selection by passing
   *          in pointers to nodes other than the root node each time.  A
   *          pointer to any node in the tree will do.  Of course, if you
   *          pass a pointer to a leaf node you'll get the same thing back.
   *
   * ------------------------------------------------------------------------ **
   */
  {
  ubi_btNodePtr follower = NULL;
  int           whichway = ubi_trLEFT;

  while( NULL != leader )
    {
    follower = leader;
    leader   = follower->Link[ whichway ];
    if( NULL == leader )
      {
      whichway = ubi_trRevWay( whichway );
      leader   = follower->Link[ whichway ];
      }
    }

  return( follower );
  } /* ubi_btLeafNode */
示例#3
0
文件: ubi_BinTree.c 项目: mbethke/hsc
ubi_btNodePtr ubi_btLeafNode( ubi_btNodePtr leader )
/* ------------------------------------------------------------------------ **
 * Returns a pointer to a leaf node.
 *
 *  Input:  leader  - Pointer to a node at which to start the descent.
 *
 *  Output: A pointer to a leaf node, selected in a somewhat arbitrary
 *          manner but with an effort to dig deep.
 *
 *  Notes:  I wrote this function because I was using splay trees as a
 *          database cache.  The cache had a maximum size on it, and I
 *          needed a way of choosing a node to sacrifice if the cache
 *          became full.  In a splay tree, less recently accessed nodes
 *          tend toward the bottom of the tree, meaning that leaf nodes
 *          are good candidates for removal.  (I really can't think of
 *          any other reason to use this function.)
 *        + In a simple binary tree, or in an AVL tree, the most recently
 *          added nodes tend to be nearer the bottom, making this a *bad*
 *          way to choose which node to remove from the cache.
 *        + Randomizing the traversal order is probably a good idea.  You
 *          can improve the randomization of leaf node selection by passing
 *          in pointers to nodes other than the root node each time.  A
 *          pointer to any node in the tree will do.  Of course, if you
 *          pass a pointer to a leaf node you'll get the same thing back.
 *        + In an unbalanced splay tree, if you simply traverse downward
 *          until you hit a leaf node it is possible to accidentally
 *          stumble onto a short path.  The result will be a leaf node
 *          that is actually very high in the tree--possibly a very
 *          recently accessed node.  Not good.  This function can follow
 *          multiple paths in an effort to find a leaf node deeper
 *          in the tree.  Following a single path, of course, is the
 *          fastest way to find a leaf node.  A complete traversal would
 *          be sure to find the deepest leaf but would be very costly in
 *          terms of time.  This function uses a compromise that has
 *          worked well in testing.
 *
 * ------------------------------------------------------------------------ **
 */
{
#define MAXPATHS 4  /* Set higher for more maximum paths, lower for fewer.  */
    ubi_trNodePtr p[MAXPATHS];
    ubi_trNodePtr q[MAXPATHS];
    int           whichway = ubi_trLEFT;
    int           paths;
    int           i, j;

    /* If the subtree is empty, return NULL.
     */
    if( NULL == leader )
        return( NULL );

    /* Initialize the p[] array with a pointer to the single node we've been
     * given as a starting point.
     */
    p[0]  = leader;
    paths = 1;
    while( paths > 0 )
    {
        for( i = 0; i < paths; i++ )
            q[i] = p[i];

        for( i = j = 0; (i < paths) && (j < MAXPATHS); i++ )
        {
            if( NULL != q[i]->Link[whichway] )
                p[j++] = q[i]->Link[whichway];
            whichway = ubi_trRevWay( whichway );
            if( (j < MAXPATHS) && (NULL != q[i]->Link[whichway]) )
                p[j++] = q[i]->Link[whichway];
        }
        paths = j;
    }

    return( q[0] );
} /* ubi_btLeafNode */