rb_walk.c

Go to the documentation of this file.
00001 /*                       R B _ W A L K . 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_walk.c
00025  *          Routines for traversal of red-black trees
00026  *
00027  *  @author -
00028  *      Paul J. Tanenbaum
00029  *
00030  *  @par Source -
00031  *      The U. S. Army Research Laboratory
00032  *      Aberdeen Proving Ground, Maryland  21005-5068  USA
00033  *
00034  *
00035  *
00036  *
00037  *
00038  *      The function bu_rb_walk() is defined in terms of the function
00039  *      _rb_walk(), which, in turn, calls any of the six functions
00040  *
00041  * @arg         - static void prewalknodes()
00042  * @arg         - static void inwalknodes()
00043  * @arg         - static void postwalknodes()
00044  * @arg         - static void prewalkdata()
00045  * @arg         - static void inwalkdata()
00046  * @arg         - static void postwalkdata()
00047  *
00048  *      depending on the type of traversal desired and the objects
00049  *      to be visited (nodes themselves, or merely the data stored
00050  *      in them).  Each of these last six functions has four parameters:
00051  *      the root of the tree to traverse, the order on which to do the
00052  *      walking, the function to apply at each visit, and the current
00053  *      depth in the tree.
00054  */
00055 /*@}*/
00056 
00057 #ifndef lint
00058 static const char libbu_rb_walk_RCSid[] = "@(#) $Header: /cvsroot/brlcad/brlcad/src/libbu/rb_walk.c,v 14.12 2006/08/31 23:16:39 lbutler Exp $";
00059 #endif
00060 
00061 #include "common.h"
00062 
00063 #include <stdlib.h>
00064 #include <stdio.h>
00065 #include <math.h>
00066 
00067 #include "machine.h"
00068 #include "rtlist.h"
00069 #include "bu.h"
00070 #include "compat4.h"
00071 #include "./rb_internals.h"
00072 
00073 
00074 /**                     P R E W A L K N O D E S ( )
00075  *
00076  *          Perform a preorder traversal of a red-black tree
00077  */
00078 static void prewalknodes (struct bu_rb_node *root, int order, void (*visit) (/* ??? */), int depth)
00079 {
00080     BU_CKMAG(root, BU_RB_NODE_MAGIC, "red-black node");
00081     BU_RB_CKORDER(root -> rbn_tree, order);
00082 
00083     if (root == bu_rb_null(root -> rbn_tree))
00084         return;
00085     visit(root, depth);
00086     prewalknodes (bu_rb_left_child(root, order), order, visit, depth + 1);
00087     prewalknodes (bu_rb_right_child(root, order), order, visit, depth + 1);
00088 }
00089 
00090 /**                     I N W A L K N O D E S ( )
00091  *
00092  *          Perform an inorder traversal of a red-black tree
00093  */
00094 static void inwalknodes (struct bu_rb_node *root, int order, void (*visit) (/* ??? */), int depth)
00095 {
00096     BU_CKMAG(root, BU_RB_NODE_MAGIC, "red-black node");
00097     BU_RB_CKORDER(root -> rbn_tree, order);
00098 
00099     if (root == bu_rb_null(root -> rbn_tree))
00100         return;
00101     inwalknodes (bu_rb_left_child(root, order), order, visit, depth + 1);
00102     visit(root, depth);
00103     inwalknodes (bu_rb_right_child(root, order), order, visit, depth + 1);
00104 }
00105 
00106 /**                     P O S T W A L K N O D E S ( )
00107  *
00108  *          Perform a postorder traversal of a red-black tree
00109  */
00110 static void postwalknodes (struct bu_rb_node *root, int order, void (*visit) (/* ??? */), int depth)
00111 {
00112     BU_CKMAG(root, BU_RB_NODE_MAGIC, "red-black node");
00113     BU_RB_CKORDER(root -> rbn_tree, order);
00114 
00115     if (root == bu_rb_null(root -> rbn_tree))
00116         return;
00117     postwalknodes (bu_rb_left_child(root, order), order, visit, depth + 1);
00118     postwalknodes (bu_rb_right_child(root, order), order, visit, depth + 1);
00119     visit(root, depth);
00120 }
00121 
00122 /**                     P R E W A L K D A T A ( )
00123  *
00124  *          Perform a preorder traversal of a red-black tree
00125  */
00126 static void prewalkdata (struct bu_rb_node *root, int order, void (*visit) (/* ??? */), int depth)
00127 {
00128     BU_CKMAG(root, BU_RB_NODE_MAGIC, "red-black node");
00129     BU_RB_CKORDER(root -> rbn_tree, order);
00130 
00131     if (root == bu_rb_null(root -> rbn_tree))
00132         return;
00133     visit(bu_rb_data(root, order), depth);
00134     prewalkdata (bu_rb_left_child(root, order), order, visit, depth + 1);
00135     prewalkdata (bu_rb_right_child(root, order), order, visit, depth + 1);
00136 }
00137 
00138 /**                     I N W A L K D A T A ( )
00139  *
00140  *          Perform an inorder traversal of a red-black tree
00141  */
00142 static void inwalkdata (struct bu_rb_node *root, int order, void (*visit) (/* ??? */), int depth)
00143 {
00144     BU_CKMAG(root, BU_RB_NODE_MAGIC, "red-black node");
00145     BU_RB_CKORDER(root -> rbn_tree, order);
00146 
00147     if (root == bu_rb_null(root -> rbn_tree))
00148         return;
00149     inwalkdata (bu_rb_left_child(root, order), order, visit, depth + 1);
00150     visit(bu_rb_data(root, order), depth);
00151     inwalkdata (bu_rb_right_child(root, order), order, visit, depth + 1);
00152 }
00153 
00154 /**                     P O S T W A L K D A T A ( )
00155  *
00156  *          Perform a postorder traversal of a red-black tree
00157  */
00158 static void postwalkdata (struct bu_rb_node *root, int order, void (*visit) (/* ??? */), int depth)
00159 {
00160     BU_CKMAG(root, BU_RB_NODE_MAGIC, "red-black node");
00161     BU_RB_CKORDER(root -> rbn_tree, order);
00162 
00163     if (root == bu_rb_null(root -> rbn_tree))
00164         return;
00165     postwalkdata (bu_rb_left_child(root, order), order, visit, depth + 1);
00166     postwalkdata (bu_rb_right_child(root, order), order, visit, depth + 1);
00167     visit(bu_rb_data(root, order), depth);
00168 }
00169 
00170 /**                     _ R B _ W A L K ( )
00171  *
00172  *                  Traverse a red-black tree
00173  *
00174  *      This function has five parameters: the tree to traverse,
00175  *      the order on which to do the walking, the function to apply
00176  *      to each node, whether to apply the function to the entire node
00177  *      (or just to its data), and the type of traversal (preorder,
00178  *      inorder, or postorder).
00179  *
00180  *      N.B. _rb_walk() is not declared static because it is called
00181  *      by bu_rb_diagnose_tree() in rb_diag.c.
00182  */
00183 void _rb_walk (bu_rb_tree *tree, int order, void (*visit) (/* ??? */), int what_to_visit, int trav_type)
00184 {
00185     static void (*walk[][3])() =
00186                 {
00187                     { prewalknodes, inwalknodes, postwalknodes },
00188                     { prewalkdata, inwalkdata, postwalkdata }
00189                 };
00190 
00191     BU_CKMAG(tree, BU_RB_TREE_MAGIC, "red-black tree");
00192     BU_RB_CKORDER(tree, order);
00193     switch (trav_type)
00194     {
00195         case PREORDER:
00196         case INORDER:
00197         case POSTORDER:
00198             switch (what_to_visit)
00199             {
00200                 case WALK_NODES:
00201                 case WALK_DATA:
00202                     (*walk[what_to_visit][trav_type])
00203                         (bu_rb_root(tree, order), order, visit, 0);
00204                     break;
00205                 default:
00206                     bu_log("FATAL: _rb_walk(): Illegal visitation object: %d\n",
00207                         what_to_visit);
00208                     bu_bomb("");
00209             }
00210             break;
00211         default:
00212             bu_log("FATAL: _rb_walk(): Illegal traversal type: %d\n",
00213                 trav_type);
00214             bu_bomb("");
00215     }
00216 }
00217 
00218 /**                     B U _ R B _ W A L K ( )
00219  *
00220  *              Applications interface to _rb_walk()
00221  *
00222  *      This function has four parameters: the tree to traverse,
00223  *      the order on which to do the walking, the function to apply
00224  *      to each node, and the type of traversal (preorder, inorder,
00225  *      or postorder).
00226  */
00227 void bu_rb_walk (bu_rb_tree *tree, int order, void (*visit) (/* ??? */), int trav_type)
00228 {
00229     BU_CKMAG(tree, BU_RB_TREE_MAGIC, "red-black tree");
00230     BU_RB_CKORDER(tree, order);
00231 
00232     _rb_walk(tree, order, visit, WALK_DATA, trav_type);
00233 }
00234 
00235 /*@}*/
00236 /*
00237  * Local Variables:
00238  * mode: C
00239  * tab-width: 8
00240  * c-basic-offset: 4
00241  * indent-tabs-mode: t
00242  * End:
00243  * ex: shiftwidth=4 tabstop=8
00244  */

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