00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
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
00054
00055
00056
00057
00058
00059
00060
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
00082
00083
00084
00085
00086
00087
00088
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
00115
00116
00117
00118
00119
00120
00121
00122
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
00152
00153
00154
00155
00156
00157
00158