rb_order_stats.c

Go to the documentation of this file.
00001 /*                R B _ O R D E R _ S T A T S . 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_order_stats.c
00025  *      Routines to support order-statistic operations for a red-black tree
00026  *
00027  *  @author
00028  *      Paul J. Tanenbaum
00029  *
00030  * @par Source -
00031  *      The U. S. Army Research Laboratory
00032  *@n    Aberdeen Proving Ground, Maryland  21005-5068  USA
00033  */
00034 /*@}*/
00035 
00036 #ifndef lint
00037 static const char libbu_rb_order_stats_RCSid[] = "@(#) $Header: /cvsroot/brlcad/brlcad/src/libbu/rb_order_stats.c,v 14.13 2006/08/31 23:16:39 lbutler Exp $";
00038 #endif
00039 
00040 #include "common.h"
00041 
00042 #include <stdlib.h>
00043 #include <stdio.h>
00044 #include <math.h>
00045 
00046 #include "machine.h"
00047 #include "rtlist.h"
00048 #include "bu.h"
00049 #include "compat4.h"
00050 #include "./rb_internals.h"
00051 
00052 
00053 /**                     _ R B _ S E L E C T ( )
00054  *
00055  *      Retrieve the element of rank k in one order of a red-black tree
00056  *
00057  *      This function has three parameters: the root of the tree to search,
00058  *      the order on which to do the searching, and the rank of interest.
00059  *      _rb_select() returns the discovered node.  It is an implemenation
00060  *      of the routine OS-SELECT on p. 282 of Cormen et al.
00061  */
00062 static struct bu_rb_node *_rb_select (struct bu_rb_node *root, int order, int k)
00063 {
00064     int         rank;
00065 
00066     BU_CKMAG(root, BU_RB_NODE_MAGIC, "red-black node");
00067 
00068     rank = bu_rb_size(bu_rb_left_child(root, order), order) + 1;
00069     if (root -> rbn_tree -> rbt_debug & BU_RB_DEBUG_OS)
00070         bu_log("_rb_select(<%x>, %d, %d): rank=%d\n",
00071             root, order, k, rank);
00072 
00073     if (rank == k)
00074         return (root);
00075     else if (rank > k)
00076         return (_rb_select(bu_rb_left_child(root, order), order, k));
00077     else
00078         return (_rb_select(bu_rb_right_child(root, order), order, k - rank));
00079 }
00080 
00081 /**                     B U _ R B _ S E L E C T ( )
00082  *
00083  *              Applications interface to _rb_select()
00084  *
00085  *      This function has three parameters: the tree in which to search,
00086  *      the order on which to do the searching, and the rank of interest.
00087  *      On success, bu_rb_select() returns a pointer to the data block in
00088  *      the discovered node.  Otherwise, it returns NULL.
00089  */
00090 void *bu_rb_select (bu_rb_tree *tree, int order, int k)
00091 {
00092     struct bu_rb_node   *node;
00093 
00094     BU_CKMAG(tree, BU_RB_TREE_MAGIC, "red-black tree");
00095     BU_RB_CKORDER(tree, order);
00096 
00097     if ((k < 1) || (k > tree -> rbt_nm_nodes))
00098     {
00099         if (tree -> rbt_debug & BU_RB_DEBUG_OS)
00100             bu_log("bu_rb_select(<%x>, %d, %d): k out of bounds [1, %d]\n",
00101                 tree, order, k, tree -> rbt_nm_nodes);
00102         bu_rb_current(tree) = bu_rb_null(tree);
00103         return (NULL);
00104     }
00105     if (tree -> rbt_debug & BU_RB_DEBUG_OS)
00106         bu_log("bu_rb_select(<%x>, %d, %d): root=<%x>\n",
00107             tree, order, k, bu_rb_root(tree, order));
00108 
00109     bu_rb_current(tree) = node
00110                         = _rb_select(bu_rb_root(tree, order), order, k);
00111     return (bu_rb_data(node, order));
00112 }
00113 
00114 /**                     B U _ R B _ R A N K ( )
00115  *
00116  *      Determines the rank of a node in one order of a red-black tree
00117  *
00118  *      This function has two parameters: the tree in which to search
00119  *      and the order on which to do the searching.  If the current node
00120  *      is null, bu_rb_rank() returns 0.  Otherwise, it returns the rank
00121  *      of the current node in the specified order.  bu_rb_rank() is an
00122  *      implementation of the routine OS-RANK on p. 283 of Cormen et al.
00123  */
00124 int bu_rb_rank (bu_rb_tree *tree, int order)
00125 {
00126     int                 rank;
00127     struct bu_rb_node   *node;
00128     struct bu_rb_node   *parent;
00129     struct bu_rb_node   *root;
00130 
00131     BU_CKMAG(tree, BU_RB_TREE_MAGIC, "red-black tree");
00132     BU_RB_CKORDER(tree, order);
00133 
00134     if ((node = bu_rb_current(tree)) == bu_rb_null(tree))
00135         return (0);
00136 
00137     root = bu_rb_root(tree, order);
00138     rank = bu_rb_size(bu_rb_left_child(node, order), order) + 1;
00139     while (node != root)
00140     {
00141         parent = bu_rb_parent(node, order);
00142         if (node == bu_rb_right_child(parent, order))
00143             rank += bu_rb_size(bu_rb_left_child(parent, order), order) + 1;
00144         node = parent;
00145     }
00146 
00147     return (rank);
00148 }
00149 /*@}*/
00150 /*
00151  * Local Variables:
00152  * mode: C
00153  * tab-width: 8
00154  * c-basic-offset: 4
00155  * indent-tabs-mode: t
00156  * End:
00157  * ex: shiftwidth=4 tabstop=8
00158  */

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