rb_extreme.c

Go to the documentation of this file.
00001 /*                    R B _ E X T R E M E . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 1998-2006 United States Government as represented by
00005  * the U.S. Army Research Laboratory.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * as published by the Free Software Foundation; either version 2 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this file; see the file named COPYING for more
00019  * information.
00020  */
00021 
00022 /** \addtogroup rb */
00023 /*@{*/
00024 /** @file rb_extreme.c
00025  *      Routines to extract mins, maxes, adjacent, and current nodes
00026  *                      from a red-black tree
00027  *
00028  *  @author
00029  *      Paul J. Tanenbaum
00030  *
00031  *  @par Source -
00032  *      The U. S. Army Research Laboratory
00033  *@n    Aberdeen Proving Ground, Maryland  21005-5068  USA
00034  */
00035 /*@}*/
00036 
00037 #ifndef lint
00038 static const char libbu_rb_extreme_RCSid[] = "@(#) $Header: /cvsroot/brlcad/brlcad/src/libbu/rb_extreme.c,v 14.13 2006/08/31 23:16:38 lbutler Exp $";
00039 #endif
00040 
00041 #include "common.h"
00042 
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045 #include <math.h>
00046 
00047 #include "machine.h"
00048 #include "rtlist.h"
00049 #include "bu.h"
00050 #include "compat4.h"
00051 #include "./rb_internals.h"
00052 
00053 
00054 /**                     _ R B _ E X T R E M E ( )
00055  *
00056  *      Find the minimum or maximum node in one order of a red-black tree
00057  *
00058  *      This function has four parameters: the root of the tree, the
00059  *      order, the sense (min or max), and the address to be understood
00060  *      as the nil node pointer. _rb_extreme() returns a pointer to the
00061  *      extreme node.
00062  */
00063 static struct bu_rb_node *_rb_extreme (struct bu_rb_node *root, int order, int sense, struct bu_rb_node *empty_node)
00064 {
00065     struct bu_rb_node   *child;
00066     bu_rb_tree          *tree;
00067 
00068     if (root == empty_node)
00069         return (root);
00070 
00071     while (1)
00072     {
00073         BU_CKMAG(root, BU_RB_NODE_MAGIC, "red-black node");
00074         tree = root -> rbn_tree;
00075         BU_RB_CKORDER(tree, order);
00076 
00077         child = (sense == SENSE_MIN) ? bu_rb_left_child(root, order) :
00078                                        bu_rb_right_child(root, order);
00079         if (child == empty_node)
00080             break;
00081         root = child;
00082     }
00083 
00084     /* Record the node with which we've been working */
00085     bu_rb_current(tree) = root;
00086 
00087     return (root);
00088 }
00089 
00090 /**                     B U _ R B _ E X T R E M E ( )
00091  *
00092  *              Applications interface to _rb_extreme()
00093  *
00094  *      This function has three parameters: the tree in which to find an
00095  *      extreme node, the order on which to do the search, and the sense
00096  *      (min or max).  On success, bu_rb_extreme() returns a pointer to the
00097  *      data in the extreme node.  Otherwise it returns NULL.
00098  */
00099 void *bu_rb_extreme (bu_rb_tree *tree, int order, int sense)
00100 {
00101     struct bu_rb_node   *node;
00102 
00103     BU_CKMAG(tree, BU_RB_TREE_MAGIC, "red-black tree");
00104     BU_RB_CKORDER(tree, order);
00105 
00106     if ((sense != SENSE_MIN) && (sense != SENSE_MAX))
00107     {
00108         bu_log("FATAL: bu_rb_extreme(): invalid sense %d, file %s, line %s\n",
00109             sense, __FILE__, __LINE__);
00110         bu_bomb("");
00111     }
00112 
00113     /* Wade throught the tree */
00114     node = _rb_extreme(bu_rb_root(tree, order), order, sense,
00115                         bu_rb_null(tree));
00116 
00117     if (node == bu_rb_null(tree))
00118         return (NULL);
00119     else
00120         return (bu_rb_data(node, order));
00121 }
00122 
00123 /**                 _ R B _ N E I G H B O R ( )
00124  *
00125  *          Return a node adjacent to a given red-black node
00126  *
00127  *      This function has three parameters: the node of interest, the
00128  *      order on which to do the search, and the sense (min or max,
00129  *      which is to say predecessor or successor).  _rb_neighbor()
00130  *      returns a pointer to the adjacent node.  This function is
00131  *      modeled after the routine TREE-SUCCESSOR on p. 249 of Cormen et al.
00132  */
00133 struct bu_rb_node *_rb_neighbor (struct bu_rb_node *node, int order, int sense)
00134 {
00135     struct bu_rb_node   *child;
00136     struct bu_rb_node   *parent;
00137     bu_rb_tree          *tree;
00138     struct bu_rb_node   *empty_node;
00139 
00140     BU_CKMAG(node, BU_RB_NODE_MAGIC, "red-black node");
00141     tree = node -> rbn_tree;
00142     BU_RB_CKORDER(tree, order);
00143 
00144     empty_node = bu_rb_null(tree);
00145 
00146     child = (sense == SENSE_MIN) ? bu_rb_left_child(node, order) :
00147                                    bu_rb_right_child(node, order);
00148     if (child != empty_node)
00149         return (_rb_extreme(child, order, 1 - sense, empty_node));
00150     parent = bu_rb_parent(node, order);
00151     while ((parent != empty_node) &&
00152            (node == bu_rb_child(parent, order, sense)))
00153     {
00154         node = parent;
00155         parent = bu_rb_parent(parent, order);
00156     }
00157 
00158     /* Record the node with which we've been working */
00159     bu_rb_current(tree) = parent;
00160 
00161     return (parent);
00162 }
00163 
00164 /**                     B U _ R B _ N E I G H B O R ( )
00165  *
00166  *          Return a node adjacent to the current red-black node
00167  *
00168  *      This function has three parameters: the tree and order on which
00169  *      to do the search and the sense (min or max, which is to say
00170  *      predecessor or successor) of the search.  bu_rb_neighbor() returns
00171  *      a pointer to the data in the node adjacent to the current node
00172  *      in the specified direction, if that node exists.  Otherwise,
00173  *      it returns NULL.
00174  */
00175 void *bu_rb_neighbor (bu_rb_tree *tree, int order, int sense)
00176 {
00177     struct bu_rb_node   *node;
00178 
00179     BU_CKMAG(tree, BU_RB_TREE_MAGIC, "red-black tree");
00180     BU_RB_CKORDER(tree, order);
00181 
00182     if ((sense != SENSE_MIN) && (sense != SENSE_MAX))
00183     {
00184         bu_log("FATAL: bu_rb_neighbor(): invalid sense %d, file %s, line %s\n",
00185             sense, __FILE__, __LINE__);
00186         bu_bomb("");
00187     }
00188 
00189     /* Wade through the tree */
00190     node = _rb_neighbor(bu_rb_current(tree), order, sense);
00191 
00192     if (node == bu_rb_null(tree))
00193         return (NULL);
00194     else
00195     {
00196         /* Record the node with which we've been working */
00197         bu_rb_current(tree) = node;
00198         return (bu_rb_data(node, order));
00199     }
00200 }
00201 
00202 /**                         B U _ R B _ C U R R ( )
00203  *
00204  *          Return the current red-black node
00205  *
00206  *      This function has two parameters: the tree and order in which
00207  *      to find the current node.  bu_rb_curr() returns a pointer to
00208  *      the data in the current node, if it exists.  Otherwise,
00209  *      it returns NULL.
00210  */
00211 void *bu_rb_curr (bu_rb_tree *tree, int order)
00212 {
00213     BU_CKMAG(tree, BU_RB_TREE_MAGIC, "red-black tree");
00214     BU_RB_CKORDER(tree, order);
00215 
00216     if (bu_rb_current(tree) == bu_rb_null(tree))
00217         return (NULL);
00218     else
00219         return (bu_rb_data(bu_rb_current(tree), order));
00220 }
00221 /*@}*/
00222 /*
00223  * Local Variables:
00224  * mode: C
00225  * tab-width: 8
00226  * c-basic-offset: 4
00227  * indent-tabs-mode: t
00228  * End:
00229  * ex: shiftwidth=4 tabstop=8
00230  */

Generated on Mon Sep 18 01:24:48 2006 for BRL-CAD by  doxygen 1.4.6