2 * Copyright (c) International Business Machines Corp., 2001-2004
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
12 * the GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 #ifndef RED_BLACK_TREE_H
19 #define RED_BLACK_TREE_H
22 * ***************************************************************************
24 * Container class for a red-black tree ......
26 * A binary tree that satisfies the following properties:
28 * 1. Every node is either red or black
29 * 2. The root node is black
30 * 3. Every leaf (NIL) is black
31 * 4. If a node is red, both its children are black
32 * 5. For each node, all paths from the node to descendant leaf nodes
33 * contain the same number of black nodes
35 * Due to points 4 & 5, the depth of a red-black tree containing n nodes
36 * is bounded by 2*log2(n+1) (WC).
39 * The rb_tree template requires two additional parmeters:
41 * - The contained TYPE class represents the objects stored in the tree.
42 * It has to support the copy constructor and the assignment operator (opr)
43 * - cmp is a functor used to define the order of objects of class TYPE:
44 * This class has to support an operator() that recieves two objects from
45 * the TYPE class and returns a negative, 0, or a positive integer,
46 * depending on the comparison result.
48 * Dominique Heger, S. Rao
50 * ***************************************************************************
53 /* Color enumeration for nodes of red-black tree */
54 /* ********************************************* */
58 typedef struct ffsb_file *datatype;
60 #define COMP_NODES(a, b) ((a)->num - (b)->num)
62 typedef enum red_black_color {red, black} rb_color;
64 /*! Representation of a node in a red-black tree */
65 typedef struct red_black_node {
66 datatype object; /* the stored object */
67 rb_color color; /* the color of the node */
68 struct red_black_node *parent; /* points to the parent node */
69 struct red_black_node *right; /* points to the right child */
70 struct red_black_node *left; /* points to the left child */
73 typedef int(cmp)(datatype, datatype);
74 typedef void(opr)(void *);
75 typedef void(destructor)(datatype);
77 /* Construct of a red-black tree node
78 * - The object stored in the node
79 * - The color of the node
82 extern rb_node *rbnode_construct(datatype object, rb_color color);
84 /* Recursive destructor for the entire sub-tree */
85 /* ******************************************** */
87 extern void rbnode_destruct(rb_node *node, destructor d);
89 /* Calculate the depth of the sub-tree spanned by the given node
91 * - The sub-tree depth
94 extern int rbnode_depth(rb_node *node);
96 /* Get the leftmost node in the sub-tree spanned by the given node
98 * - The sub-tree minimum
101 extern rb_node *rbnode_minimum(rb_node *node);
103 /* Get the rightmost node in the sub-tree spanned by the given node
104 * - The sub-tree root
105 * - The sub-tree maximum
108 extern rb_node *rbnode_maximum(rb_node *node);
110 /* Replace the object */
111 /* ****************** */
113 extern void rbnode_replace(rb_node *node, datatype object);
115 /* Get the next node in the tree (according to the tree order)
117 * - The successor node, or NULL if node is the tree maximum
120 extern rb_node *rbnode_successor(rb_node *node);
122 /* Get the previous node in the tree (according to the tree order)
124 * - The predecessor node, or NULL if node is the tree minimum
127 extern rb_node *rbnode_predecessor(rb_node *node);
129 /* Duplicate the entire sub-tree rooted at the given node
130 * - The sub-tree root
131 * - A pointer to the duplicated sub-tree root
134 extern rb_node *rbnode_duplicate(rb_node *node);
136 /* Traverse a red-black sub-tree
137 * - The sub-tree root
138 * - The operation to perform on each object in the sub-tree
140 extern void rbnode_traverse(rb_node *node, opr *op);
142 /* Representation of a red-black tree */
143 /* ********************************** */
145 typedef struct red_black_tree {
146 rb_node *root; /* pointer to the tree root */
147 int isize; /* number of objects stored */
148 /* cmp * comp; */ /* compare function */
151 /* Initialize a red-black tree with a comparision function
153 * - The comparision function
156 void rbtree_init(rb_tree *tree);
158 /* Construct a red-black tree with a comparison object
159 * - A pointer to the comparison object to be used by the tree
160 * - The newly constructed tree
163 rb_tree *rbtree_construct(void);
165 /* Clean a red-black tree [takes O(n) operations]
169 extern void rbtree_clean(rb_tree *tree, destructor d);
171 /* Destruct a red-black tree
175 extern void rbtree_destruct(rb_tree *tree, destructor d);
177 /* Get the size of the tree [takes O(1) operations]
179 * - The number of objects stored in the tree
182 extern int rbtree_size(rb_tree *tree);
184 /* Get the depth of the tree [takes O(n) operations]
186 * - The length of the longest path from the root to a leaf node
189 extern int rbtree_depth(rb_tree *tree);
191 /* Check whether the tree contains an object [takes O(log n) operations]
194 * - (true) if an equal object is found in the tree, otherwise (false)
197 extern int rbtree_contains(rb_tree *tree, datatype object);
199 /* Insert an object to the tree [takes O(log n) operations]
201 * - The object to be inserted
202 * - Return the inserted object node
205 extern rb_node *rbtree_insert(rb_tree *tree, datatype object);
207 /* Insert a new object to the tree as the a successor of a given node
212 extern rb_node *insert_successor_at(rb_tree *tree, rb_node *at_node,
215 /* Insert a new object to the tree as the a predecessor of a given node
220 extern rb_node *insert_predecessor_at(rb_tree *tree, rb_node *at_node,
223 /* Remove an object from the tree [takes O(log n) operations]
225 * - The object to be removed
226 * - The object should be contained in the tree
229 extern void rbtree_remove(rb_tree *tree, datatype object, destructor d);
231 /* Get a handle to the tree minimum [takes O(log n) operations]
233 * - Return the minimal object in the tree, or a NULL if the tree is empty
236 extern rb_node *rbtree_minimum(rb_tree *tree);
238 /* Get a handle to the tree maximum [takes O(log n) operations]
240 * - Return the maximal object in the tree, or a NULL if the tree is empty
243 extern rb_node *rbtree_maximum(rb_tree *tree);
245 /* Get the next node in the tree (according to the tree order)
246 * - [takes O(log n) operations at worst-case, but only O(1) amortized]
248 * - The current object
249 * - The successor node, or a NULL, if we are at the tree maximum
251 extern rb_node *rbtree_successor(rb_tree *tree, rb_node *node);
253 /* Get the previous node in the tree (according to the tree order)
254 * - [takes O(log n) operations at worst-case, but only O(1) amortized]
256 * - The current object
257 * - The predecessor node, or a NULL, if we are at the tree minimum
260 extern rb_node *rbtree_predecessor(rb_tree *tree, rb_node *node);
262 /* Find a node that contains the given object
264 * - The desired object
265 * - Return a node that contains the given object, or NULL if no such object
266 * is found in the tree
269 extern rb_node *rbtree_find(rb_tree *tree, datatype object);
271 /* Remove the object stored in the given tree node
273 * - The node storing the object to be removed from the tree
276 extern void rbtree_remove_at(rb_tree *tree, rb_node *node, destructor d);
278 /* Left-rotate the sub-tree spanned by the given node
280 * - The sub-tree root
283 extern void rbtree_rotate_left(rb_tree *tree, rb_node *node);
285 /* Right-rotate the sub-tree spanned by the given node
287 * - The sub-tree root
290 extern void rbtree_rotate_right(rb_tree *tree, rb_node *node);
293 * Fix the red-black tree properties after an insertion operation
295 * - The node that has just been inserted to the tree
296 * - The color of node must be red
299 extern void rbtree_insert_fixup(rb_tree *tree, rb_node *node);
301 /* Fix the red-black tree properties after a removal operation
303 * - The child of the node that has just been removed from the tree
306 extern void rbtree_remove_fixup(rb_tree *tree, rb_node *node);
308 /* Traverse a red-black tree
310 * - The operation to perform on every object of the tree (according to
314 extern void rbtree_traverse(rb_tree *tree, opr *op);