• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   *   Copyright (c) International Business Machines Corp., 2001-2004
3   *
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.
8   *
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.
13   *
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17   */
18  #include <stdio.h>
19  #include <stdlib.h>
20  #include <assert.h>
21  #include "rbt.h"
22  
23  /*
24   * ***********************************************
25   *
26   * D.H. IBM, S. Rao
27   *
28   * Module: Operations executed on red-black struct
29   *
30   * ***********************************************
31   */
32  
33  /* Construct a red-black tree node */
34  
rbnode_construct(datatype object,rb_color color)35  rb_node *rbnode_construct(datatype object, rb_color color)
36  {
37  	rb_node *node = (rb_node *) malloc(sizeof(rb_node));
38  	if (!node) {
39  		fprintf(stderr, "Memory Shortage - No Execution Possible\n");
40  		return NULL;
41  	}
42  	node->object = object;
43  	node->color = color;
44  	node->parent = node->right = node->left = NULL;
45  	return node;
46  }
47  
48  /* Destructor of a red-black tree node */
49  
rbnode_destruct(rb_node * node,destructor d)50  void rbnode_destruct(rb_node * node, destructor d)
51  {
52  	if (!node)
53  		return;
54  	if (d != NULL)
55  		d(node->object);
56  	rbnode_destruct(node->right, d);
57  	rbnode_destruct(node->left, d);
58  	free(node);
59  }
60  
61  /* Determine the depth of the subtree spanned by a given node */
62  
rbnode_depth(rb_node * node)63  int rbnode_depth(rb_node * node)
64  {
65  	/* Recursively determine the depth of the left and right
66  	 * subtrees
67  	 */
68  	int irightdepth = (node->right) ? rbnode_depth(node->right) : 0;
69  	int ileftdepth = (node->left) ? rbnode_depth(node->left) : 0;
70  
71  	/* Return the maximal child depth + 1 (the current node) */
72  	return ((irightdepth >
73  		 ileftdepth) ? (irightdepth + 1) : (ileftdepth + 1));
74  }
75  
76  /* Return the leftmost leaf in the tree */
77  
rbnode_minimum(rb_node * node)78  rb_node *rbnode_minimum(rb_node * node)
79  {
80  	while (node->left)
81  		node = node->left;
82  	return node;
83  }
84  
85  /* Return the rightmost leaf in the tree */
86  
rbnode_maximum(rb_node * node)87  rb_node *rbnode_maximum(rb_node * node)
88  {
89  	while (node->right)
90  		node = node->right;
91  	return node;
92  }
93  
94  /* Replace an object */
95  
rbnode_replace(rb_node * node,datatype object)96  void rbnode_replace(rb_node * node, datatype object)
97  {
98  	/* Make sure the replacement does not violate the tree order
99  	 * Replace the object at the node
100  	 */
101  	node->object = object;
102  }
103  
104  /* Get the next node in the tree (according to the tree order) */
105  
rbnode_successor(rb_node * node)106  rb_node *rbnode_successor(rb_node * node)
107  {
108  	rb_node *succ_node;
109  
110  	if (node->right) {
111  
112  		/* If there is a right child, the successor is the
113  		 * minimal object in the sub-tree spanned by this
114  		 * child.
115  		 */
116  
117  		succ_node = node->right;
118  		while (succ_node->left)
119  			succ_node = succ_node->left;
120  	} else {
121  
122  		/* Otherwise, go up the tree until reaching the parent
123  		 * from the left direction.
124  		 */
125  
126  		rb_node *prev_node = node;
127  		succ_node = node->parent;
128  		while (succ_node && prev_node == succ_node->right) {
129  			prev_node = succ_node;
130  			succ_node = succ_node->parent;
131  		}
132  	}
133  
134  	return (succ_node);
135  }
136  
137  /* Get the previous node in the tree (according to the tree order) */
138  
rbnode_predecessor(rb_node * node)139  rb_node *rbnode_predecessor(rb_node * node)
140  {
141  	rb_node *pred_node;
142  
143  	if (node->left) {
144  
145  		/* If there is a left child, the predecessor is the
146  		 * maximal object in the sub-tree spanned by this
147  		 * child.
148  		 */
149  
150  		pred_node = node->left;
151  		while (pred_node->right)
152  			pred_node = pred_node->right;
153  	} else {
154  
155  		/* Otherwise, go up the tree until reaching the parent
156  		 * from the right direction.
157  		 */
158  
159  		rb_node *prev_node = node;
160  		pred_node = node->parent;
161  		while (pred_node && prev_node == pred_node->left) {
162  			prev_node = pred_node;
163  			pred_node = pred_node->parent;
164  		}
165  	}
166  
167  	return (pred_node);
168  }
169  
170  /* Return a pointer to a duplication of the given node */
171  
rbnode_duplicate(rb_node * node)172  rb_node *rbnode_duplicate(rb_node * node)
173  {
174  	/* Create a node of the same color, containing the same
175  	 * object
176  	 */
177  	rb_node *dup_node = rbnode_construct(node->object, node->color);
178  	if (!dup_node)
179  		return NULL;
180  
181  	/* Duplicate the children recursively */
182  	if (node->right) {
183  		dup_node->right = rbnode_duplicate(node->right);
184  		dup_node->right->parent = dup_node;
185  	} else {
186  		dup_node->right = NULL;
187  	}
188  
189  	if (node->left) {
190  		dup_node->left = rbnode_duplicate(node->left);
191  		dup_node->left->parent = dup_node;
192  	} else {
193  		dup_node->left = NULL;
194  	}
195  
196  	return dup_node;	/* Return the duplicated node */
197  }
198  
199  /* Traverse a red-black subtree */
200  
rbnode_traverse(rb_node * node,opr * op)201  void rbnode_traverse(rb_node * node, opr * op)
202  {
203  	if (!node)
204  		return;
205  	rbnode_traverse(node->left, op);
206  	op(node->object);
207  	rbnode_traverse(node->right, op);
208  }
209  
210  /*
211   * ***********************************
212   *
213   * Operations on rb_tree struct
214   *
215   * ***********************************
216   */
217  
218  /* Intialize a tree */
rbtree_init(rb_tree * tree)219  void rbtree_init(rb_tree * tree)
220  {
221  /*   tree->comp = comp; */
222  	tree->isize = 0;
223  	tree->root = NULL;
224  }
225  
226  /* Construct a tree given a comparison function */
227  
rbtree_construct()228  rb_tree *rbtree_construct()
229  {
230  	rb_tree *tree = (rb_tree *) malloc(sizeof(rb_tree));
231  	if (!tree) {
232  		fprintf(stderr, "Memory Issue - Shortge Exists!\n");
233  		return NULL;
234  	}
235  	rbtree_init(tree);
236  	return tree;
237  }
238  
239  /* Remove all objects from a black-red tree */
240  
rbtree_clean(rb_tree * tree,destructor d)241  void rbtree_clean(rb_tree * tree, destructor d)
242  {
243  	if (tree->root)
244  		rbnode_destruct(tree->root, d);
245  	tree->root = NULL;
246  	tree->isize = 0;
247  }
248  
249  /* Destruct a red-black tree */
250  
rbtree_destruct(rb_tree * tree,destructor d)251  void rbtree_destruct(rb_tree * tree, destructor d)
252  {
253  	rbtree_clean(tree, d);
254  	free(tree);
255  }
256  
257  /* Returns the size of the tree */
258  
rbtree_size(rb_tree * tree)259  int rbtree_size(rb_tree * tree)
260  {
261  	return tree->isize;
262  }
263  
264  /* Returns the depth of the tree */
265  
rbtree_depth(rb_tree * tree)266  int rbtree_depth(rb_tree * tree)
267  {
268  	if (!(tree->root))
269  		return 0;
270  	return rbnode_depth(tree->root);
271  }
272  
273  /* Check whether the tree contains a certain object */
274  
rbtree_contains(rb_tree * tree,datatype object)275  int rbtree_contains(rb_tree * tree, datatype object)
276  {
277  	return (rbtree_find(tree, object) != NULL);
278  }
279  
280  /* Insert an object into the rb-tree */
281  
rbtree_insert(rb_tree * tree,datatype object)282  rb_node *rbtree_insert(rb_tree * tree, datatype object)
283  {
284  	rb_node *cur_node;
285  	rb_node *new_node;
286  	int comp_result = 0;
287  
288  	if (!(tree->root)) {
289  		/* Assign a new root node (the root is always
290  		 * black)
291  		 */
292  		new_node = rbnode_construct(object, black);
293  		if (!new_node)
294  			return NULL;
295  		tree->root = new_node;
296  		tree->isize = 1;
297  		return new_node;
298  	}
299  
300  	/* Find a spot for the new object, insert the object as a red
301  	 * leaf
302  	 */
303  
304  	cur_node = tree->root;
305  	new_node = rbnode_construct(object, red);
306  	if (!new_node)
307  		return NULL;
308  
309  	while (cur_node) {
310  		/* Compare inserted object with the object stored in
311  		 * the current node
312  		 */
313  		comp_result = COMP_NODES(object, cur_node->object);
314  		if (comp_result == 0) {
315  			printf
316  			    ("Attempted to insert duplicate node, aborting\n");
317  			free(new_node);
318  			return NULL;
319  		}
320  		if (comp_result > 0) {
321  			if (!(cur_node->left)) {
322  				/* Insert the new leaf as the left
323  				 * child of the current node
324  				 */
325  				cur_node->left = new_node;
326  				new_node->parent = cur_node;
327  				cur_node = NULL;	/* Terminate the while loop */
328  			} else {
329  				/* Go to the left subtree */
330  				cur_node = cur_node->left;
331  			}
332  		} else {
333  			if (!(cur_node->right)) {
334  				/* Insert the new leaf as the right
335  				 * child of the current node
336  				 */
337  				cur_node->right = new_node;
338  				new_node->parent = cur_node;
339  				cur_node = NULL;	/* Terminate the while loop */
340  			} else {
341  				/* Go to the right subtree */
342  				cur_node = cur_node->right;
343  			}
344  		}
345  	}
346  
347  	/* Mark the fact that a new node was added */
348  	tree->isize++;
349  
350  	/* Fix the tree properties */
351  	rbtree_insert_fixup(tree, new_node);
352  
353  	return new_node;
354  }
355  
356  /* Insert a new object to the tree as the a successor of a given
357   * node
358   */
359  
insert_successor_at(rb_tree * tree,rb_node * at_node,datatype object)360  rb_node *insert_successor_at(rb_tree * tree, rb_node * at_node, datatype object)
361  {
362  	rb_node *parent;
363  	rb_node *new_node;
364  
365  	if (!(tree->root)) {
366  		/* Assign a new root node (the root is always
367  		 * black)
368  		 */
369  		new_node = rbnode_construct(object, black);
370  		if (!new_node)
371  			return NULL;
372  		tree->root = new_node;
373  		tree->isize = 1;
374  		return new_node;
375  	}
376  
377  	/* Insert the new object as a red leaf, being the successor of
378  	 * node
379  	 */
380  	new_node = rbnode_construct(object, red);
381  	if (!new_node)
382  		return NULL;
383  
384  	if (!at_node) {
385  		/* The new node should become the tree's minimum Place
386  		 * is as the left child of the current minimal leaf
387  		 */
388  		parent = rbnode_minimum(tree->root);
389  		parent->left = new_node;
390  	} else {
391  		/* Make sure the insertion does not violate the tree
392  		 * order In case given node has no right child, place
393  		 * the new node as its right child. Otherwise, place
394  		 * it at the leftmost position at the sub-tree rooted
395  		 * at its right side.
396  		 */
397  		if (!at_node->right) {
398  			parent = at_node;
399  			parent->right = new_node;
400  		} else {
401  			parent = rbnode_minimum(at_node->right);
402  			parent->left = new_node;
403  		}
404  	}
405  
406  	new_node->parent = parent;
407  
408  	/* Mark that a new node was added */
409  	tree->isize++;
410  
411  	/* Fix the tree properties */
412  	rbtree_insert_fixup(tree, new_node);
413  
414  	return new_node;
415  }
416  
417  /* Insert a new object to the tree as the a predecessor of a given node */
418  
insert_predecessor_at(rb_tree * tree,rb_node * at_node,datatype object)419  rb_node *insert_predecessor_at(rb_tree * tree, rb_node * at_node,
420  			       datatype object)
421  {
422  	rb_node *parent;
423  	rb_node *new_node;
424  
425  	if (!(tree->root)) {
426  		/* Assign a new root node (the root is always
427  		 * black)
428  		 */
429  		new_node = rbnode_construct(object, black);
430  		if (!new_node)
431  			return NULL;
432  		tree->root = new_node;
433  		tree->isize = 1;
434  		return new_node;
435  	}
436  
437  	/* Insert the new object as a red leaf, being the predecessor
438  	 * of at_node
439  	 */
440  	new_node = rbnode_construct(object, red);
441  	if (!new_node)
442  		return NULL;
443  
444  	if (!at_node) {
445  		/* The new node should become the tree maximum. Place
446  		 * is as the right child of the current maximal leaf
447  		 */
448  		parent = rbnode_maximum(tree->root);
449  		parent->right = new_node;
450  	} else {
451  		/* Make sure the insertion does not violate the tree
452  		 * order In case given node has no left child, place
453  		 * the new node as its left child. Otherwise, place it
454  		 * at the rightmost position at the sub-tree rooted at
455  		 * its left side.
456  		 */
457  		if (!(at_node->left)) {
458  			parent = at_node;
459  			parent->left = new_node;
460  		} else {
461  			parent = rbnode_maximum(at_node->left);
462  			parent->right = new_node;
463  		}
464  	}
465  
466  	new_node->parent = parent;
467  
468  	/* Mark that a new node was added */
469  	tree->isize++;
470  
471  	/* Fix the tree properties */
472  	rbtree_insert_fixup(tree, new_node);
473  
474  	return new_node;
475  }
476  
477  /* Remove an object from the tree */
478  
rbtree_remove(rb_tree * tree,datatype object,destructor d)479  void rbtree_remove(rb_tree * tree, datatype object, destructor d)
480  {
481  	rb_node *node = rbtree_find(tree, object);	/* Find the node */
482  	rbtree_remove_at(tree, node, d);	/* Remove the node */
483  }
484  
485  /* Remove the object pointed by the given node. */
486  
rbtree_remove_at(rb_tree * tree,rb_node * node,destructor d)487  void rbtree_remove_at(rb_tree * tree, rb_node * node, destructor d)
488  {
489  	rb_node *child = NULL;
490  
491  	/* In case of deleting the single object stored in the tree,
492  	 * free the root, thus emptying the tree
493  	 */
494  	if (tree->isize == 1) {
495  		rbnode_destruct(tree->root, d);
496  		tree->root = NULL;
497  		tree->isize = 0;
498  		return;
499  	}
500  
501  	/* Remove the given node from the tree */
502  	if (node->left && node->right) {
503  		/* If the node we want to remove has two children,
504  		 * find its successor, which is the leftmost child in
505  		 * its right sub-tree and has at most one child (it
506  		 * may have a right child).
507  		 */
508  		rb_node *succ_node = rbnode_minimum(node->right);
509  
510  		/* Now physically swap node and its successor. Notice
511  		 * this may temporarily violate the tree properties,
512  		 * but we are going to remove node anyway.  This way
513  		 * we have moved node to a position were it is more
514  		 * convinient to delete it.
515  		 */
516  		int immediate_succ = (node->right == succ_node);
517  		rb_node *succ_parent = succ_node->parent;
518  		rb_node *succ_left = succ_node->left;
519  		rb_node *succ_right = succ_node->right;
520  		rb_color succ_color = succ_node->color;
521  
522  		succ_node->parent = node->parent;
523  		succ_node->left = node->left;
524  		succ_node->right = immediate_succ ? node : node->right;
525  		succ_node->color = node->color;
526  
527  		node->parent = immediate_succ ? succ_node : succ_parent;
528  		node->left = succ_left;
529  		node->right = succ_right;
530  		node->color = succ_color;
531  
532  		if (!immediate_succ) {
533  			if (succ_node == node->parent->left)
534  				node->parent->left = node;
535  			else
536  				node->parent->right = node;
537  		}
538  
539  		if (node->left)
540  			node->left->parent = node;
541  		if (node->right)
542  			node->right->parent = node;
543  
544  		if (succ_node->parent) {
545  			if (node == succ_node->parent->left)
546  				succ_node->parent->left = succ_node;
547  			else
548  				succ_node->parent->right = succ_node;
549  		} else {
550  			tree->root = succ_node;
551  		}
552  
553  		if (succ_node->left)
554  			succ_node->left->parent = succ_node;
555  		if (succ_node->right)
556  			succ_node->right->parent = succ_node;
557  	}
558  
559  	/* At this stage, the node we are going to remove has at most
560  	 * one child
561  	 */
562  	child = (node->left) ? node->left : node->right;
563  
564  	/* Splice out the node to be removed, by linking its parent
565  	 * straight to the removed node's single child.
566  	 */
567  	if (child)
568  		child->parent = node->parent;
569  
570  	if (!(node->parent)) {
571  		/* If we are deleting the root, make the child the new
572  		 * tree node
573  		 */
574  		tree->root = child;
575  	} else {
576  		/* Link the removed node parent to its child */
577  		if (node == node->parent->left)
578  			node->parent->left = child;
579  		else
580  			node->parent->right = child;
581  	}
582  
583  	/* Fix-up the red-black properties that may have been damaged:
584  	 * If we have just removed a black node, the black-depth
585  	 * property is no longer valid
586  	 */
587  	if (node->color == black && child)
588  		rbtree_remove_fixup(tree, child);
589  
590  	/* Delete the un-necessary node (nullify both its children
591  	 * because the node's destructor is recursive).
592  	 */
593  	node->left = NULL;
594  	node->right = NULL;
595  	free(node);
596  
597  	/* Decrease the number of objects in the tree */
598  	tree->isize--;
599  }
600  
601  /* Get the tree minimum */
602  
rbtree_minimum(rb_tree * tree)603  rb_node *rbtree_minimum(rb_tree * tree)
604  {
605  	if (!(tree->root))
606  		return NULL;
607  
608  	/* Return the leftmost leaf in the tree */
609  	return rbnode_minimum(tree->root);
610  }
611  
612  /* Get the tree maximum */
613  
rbtree_maximum(rb_tree * tree)614  rb_node *rbtree_maximum(rb_tree * tree)
615  {
616  	if (!(tree->root))
617  		return NULL;
618  
619  	/* Return the rightmost leaf in the tree */
620  	return rbnode_maximum(tree->root);
621  }
622  
623  /* Return a pointer to the node containing the given object */
624  
rbtree_find(rb_tree * tree,datatype object)625  rb_node *rbtree_find(rb_tree * tree, datatype object)
626  {
627  	rb_node *cur_node = tree->root;
628  	int comp_result;
629  
630  	while (cur_node) {
631  		comp_result = COMP_NODES(object, cur_node->object);
632  		/* In case of equality, we can return the current
633  		 * node.
634  		 */
635  		if (comp_result == 0)
636  			return cur_node;
637  		/* Go down to the left or right child. */
638  		cur_node = (comp_result > 0) ? cur_node->left : cur_node->right;
639  	}
640  
641  	/* If we get here, the object is not in the tree */
642  	return NULL;
643  }
644  
rbtree_rotate_left(rb_tree * tree,rb_node * x_node)645  void rbtree_rotate_left(rb_tree * tree, rb_node * x_node)
646  {
647  	/* Get the right child of the node */
648  	rb_node *y_node = x_node->right;
649  
650  	/* Change its left subtree (T2) to x's right subtree */
651  	x_node->right = y_node->left;
652  
653  	/* Link T2 to its new parent x */
654  	if (y_node->left != NULL)
655  		y_node->left->parent = x_node;
656  
657  	/* Assign x's parent to be y's parent */
658  	y_node->parent = x_node->parent;
659  
660  	if (!(x_node->parent)) {
661  		/* Make y the new tree root */
662  		tree->root = y_node;
663  	} else {
664  		/* Assign a pointer to y from x's parent */
665  		if (x_node == x_node->parent->left)
666  			x_node->parent->left = y_node;
667  		else
668  			x_node->parent->right = y_node;
669  	}
670  
671  	/* Assign x to be y's left child */
672  	y_node->left = x_node;
673  	x_node->parent = y_node;
674  }
675  
676  /* Right-rotate the sub-tree spanned by the given node */
677  
rbtree_rotate_right(rb_tree * tree,rb_node * y_node)678  void rbtree_rotate_right(rb_tree * tree, rb_node * y_node)
679  {
680  	/* Get the left child of the node */
681  	rb_node *x_node = y_node->left;
682  
683  	/* Change its right subtree (T2) to y's left subtree */
684  	y_node->left = x_node->right;
685  
686  	/* Link T2 to its new parent y */
687  	if (x_node->right != NULL)
688  		x_node->right->parent = y_node;
689  
690  	/* Assign y's parent to be x's parent */
691  	x_node->parent = y_node->parent;
692  
693  	if (!(y_node->parent)) {
694  		/* Make x the new tree root */
695  		tree->root = x_node;
696  	} else {
697  		/* Assign a pointer to x from y's parent */
698  		if (y_node == y_node->parent->left)
699  			y_node->parent->left = x_node;
700  		else
701  			y_node->parent->right = x_node;
702  	}
703  
704  	/* Assign y to be x's right child */
705  	x_node->right = y_node;
706  	y_node->parent = x_node;
707  }
708  
709  /* Fix the tree so it maintains the red-black properties after an insert */
710  
rbtree_insert_fixup(rb_tree * tree,rb_node * node)711  void rbtree_insert_fixup(rb_tree * tree, rb_node * node)
712  {
713  	/* Fix the red-black propreties. We may have inserted a red
714  	 * leaf as the child of a red parent - so we have to fix the
715  	 * coloring of the parent recursively.
716  	 */
717  	rb_node *curr_node = node;
718  	rb_node *grandparent;
719  	rb_node *uncle;
720  
721  	assert(node && node->color == red);
722  
723  	while (curr_node != tree->root && curr_node->parent->color == red) {
724  		/* Get a pointer to the current node's grandparent
725  		 * (the root is always black, so the red parent must
726  		 * have a parent).
727  		 */
728  
729  		grandparent = curr_node->parent->parent;
730  
731  		if (curr_node->parent == grandparent->left) {
732  			/* If the red parent is a left child, the
733  			 * uncle is the right child of the grandparent.
734  			 */
735  			uncle = grandparent->right;
736  
737  			if (uncle && uncle->color == red) {
738  
739  				/* If both parent and uncle are red,
740  				 * color them black and color the
741  				 * grandparent red. In case of a NULL
742  				 * uncle, treat it as a black node
743  				 */
744  				curr_node->parent->color = black;
745  				uncle->color = black;
746  				grandparent->color = red;
747  
748  				/* Move to the grandparent */
749  				curr_node = grandparent;
750  			} else {
751  				/* Make sure the current node is a
752  				 * right child. If not, left-rotate the
753  				 * parent's sub-tree so the parent
754  				 * becomes the right child of the
755  				 * current node (see _rotate_left).
756  				 */
757  				if (curr_node == curr_node->parent->right) {
758  					curr_node = curr_node->parent;
759  					rbtree_rotate_left(tree, curr_node);
760  				}
761  
762  				/* Color the parent black and the
763  				 * grandparent red
764  				 */
765  				curr_node->parent->color = black;
766  				grandparent->color = red;
767  
768  				/* Right-rotate the grandparent's
769  				 * sub-tree
770  				 */
771  				rbtree_rotate_right(tree, grandparent);
772  			}
773  		} else {
774  			/* If the red parent is a right child, the
775  			 * uncle is the left child of the grandparent.
776  			 */
777  			uncle = grandparent->left;
778  
779  			if (uncle && uncle->color == red) {
780  				/* If both parent and uncle are red,
781  				 * color them black and color the
782  				 * grandparent red. In case of a NULL
783  				 * uncle, treat it as a black node
784  				 */
785  				curr_node->parent->color = black;
786  				uncle->color = black;
787  				grandparent->color = red;
788  
789  				/* Move to the grandparent */
790  				curr_node = grandparent;
791  			} else {
792  				/* Make sure the current node is a
793  				 * left child. If not, right-rotate
794  				 * the parent's sub-tree so the parent
795  				 * becomes the left child of the
796  				 * current node.
797  				 */
798  				if (curr_node == curr_node->parent->left) {
799  					curr_node = curr_node->parent;
800  					rbtree_rotate_right(tree, curr_node);
801  				}
802  
803  				/* Color the parent black and the
804  				 * grandparent red
805  				 */
806  				curr_node->parent->color = black;
807  				grandparent->color = red;
808  
809  				/* Left-rotate the grandparent's
810  				 * sub-tree
811  				 */
812  				rbtree_rotate_left(tree, grandparent);
813  			}
814  		}
815  	}
816  
817  	/* Make sure that the root is black */
818  	tree->root->color = black;
819  }
820  
rbtree_remove_fixup(rb_tree * tree,rb_node * node)821  void rbtree_remove_fixup(rb_tree * tree, rb_node * node)
822  {
823  	rb_node *curr_node = node;
824  	rb_node *sibling;
825  
826  	while (curr_node != tree->root && curr_node->color == black) {
827  		/* Get a pointer to the current node's sibling (notice
828  		 * that the node's parent must exist, since the node
829  		 * is not the root).
830  		 */
831  		if (curr_node == curr_node->parent->left) {
832  			/* If the current node is a left child, its
833  			 * sibling is the right child of the parent.
834  			 */
835  			sibling = curr_node->parent->right;
836  
837  			/* Check the sibling's color. Notice that NULL
838  			 * nodes are treated as if they are colored
839  			 * black.
840  			 */
841  			if (sibling && sibling->color == red) {
842  				/* In case the sibling is red, color
843  				 * it black and rotate.  Then color
844  				 * the parent red (the grandparent is
845  				 * now black)
846  				 */
847  				sibling->color = black;
848  				curr_node->parent->color = red;
849  				rbtree_rotate_left(tree, curr_node->parent);
850  				sibling = curr_node->parent->right;
851  			}
852  
853  			if (sibling &&
854  			    (!(sibling->left) || sibling->left->color == black)
855  			    && (!(sibling->right)
856  				|| sibling->right->color == black)) {
857  				/* If the sibling has two black
858  				 * children, color it red
859  				 */
860  				sibling->color = red;
861  				if (curr_node->parent->color == red) {
862  					/* If the parent is red, we
863  					 * can safely color it black
864  					 * and terminate the fix
865  					 * process.
866  					 */
867  					curr_node->parent->color = black;
868  					/* In order to stop the while loop */
869  					curr_node = tree->root;
870  				} else {
871  					/* The black depth of the
872  					 * entire sub-tree rooted at
873  					 * the parent is now too small
874  					 * - fix it up recursively.
875  					 */
876  					curr_node = curr_node->parent;
877  				}
878  			} else {
879  				if (!sibling) {
880  					/* Take special care of the
881  					 * case of a NULL sibling
882  					 */
883  					if (curr_node->parent->color == red) {
884  						curr_node->parent->color =
885  						    black;
886  						/* In order to stop
887  						 * the while loop */
888  						curr_node = tree->root;
889  					} else {
890  						curr_node = curr_node->parent;
891  					}
892  				} else {
893  					/* In this case, at least one
894  					 * of the sibling's children
895  					 * is red.  It is therfore
896  					 * obvious that the sibling
897  					 * itself is black.
898  					 */
899  					if (sibling->right
900  					    && sibling->right->color == red) {
901  						/* If the right child
902  						 * of the sibling is
903  						 * red, color it black
904  						 * and rotate around
905  						 * the current parent.
906  						 */
907  						sibling->right->color = black;
908  						rbtree_rotate_left(tree,
909  								   curr_node->
910  								   parent);
911  					} else {
912  						/* If the left child
913  						 * of the sibling is
914  						 * red, rotate around
915  						 * the sibling, then
916  						 * rotate around the
917  						 * new sibling of our
918  						 * current node.
919  						 */
920  						rbtree_rotate_right(tree,
921  								    sibling);
922  						sibling =
923  						    curr_node->parent->right;
924  						rbtree_rotate_left(tree,
925  								   sibling);
926  					}
927  
928  					/* It is now safe to color the
929  					 * parent black and to
930  					 * terminate the fix process.
931  					 */
932  					if (curr_node->parent->parent)
933  						curr_node->parent->parent->
934  						    color =
935  						    curr_node->parent->color;
936  					curr_node->parent->color = black;
937  					/* In order to stop the while loop */
938  					curr_node = tree->root;
939  				}
940  			}
941  		} else {
942  			/* If the current node is a right child, its
943  			 * sibling is the left child of the parent.
944  			 */
945  			sibling = curr_node->parent->left;
946  
947  			/* Check the sibling's color. Notice that NULL
948  			 * nodes are treated as if they are colored
949  			 * black.
950  			 */
951  			if (sibling && sibling->color == red) {
952  				/* In case the sibling is red, color
953  				 * it black and rotate.  Then color
954  				 * the parent red (the grandparent is
955  				 * now black).
956  				 */
957  				sibling->color = black;
958  				curr_node->parent->color = red;
959  				rbtree_rotate_right(tree, curr_node->parent);
960  
961  				sibling = curr_node->parent->left;
962  			}
963  
964  			if (sibling &&
965  			    (!(sibling->left) || sibling->left->color == black)
966  			    && (!(sibling->right)
967  				|| sibling->right->color == black)) {
968  				/* If the sibling has two black children, color it red */
969  				sibling->color = red;
970  				if (curr_node->parent->color == red) {
971  					/* If the parent is red, we
972  					 * can safely color it black
973  					 * and terminate the fix-up
974  					 * process.
975  					 */
976  					curr_node->parent->color = black;
977  					/* In order to stop the while
978  					 * loop
979  					 */
980  					curr_node = tree->root;
981  				} else {
982  					/* The black depth of the
983  					 * entire sub-tree rooted at
984  					 * the parent is now too small
985  					 * - fix it up recursively.
986  					 */
987  					curr_node = curr_node->parent;
988  				}
989  			} else {
990  				if (!sibling) {
991  					/* Take special care of the
992  					 * case of a NULL sibling */
993  					if (curr_node->parent->color == red) {
994  						curr_node->parent->color =
995  						    black;
996  						/* In order to stop
997  						 * the while loop */
998  						curr_node = tree->root;
999  					} else {
1000  						curr_node = curr_node->parent;
1001  					}
1002  				} else {
1003  					/* In this case, at least one
1004  					 * of the sibling's children is
1005  					 * red.  It is therfore obvious
1006  					 * that the sibling itself is
1007  					 * black.
1008  					 */
1009  					if (sibling->left
1010  					    && sibling->left->color == red) {
1011  						/* If the left child
1012  						 * of the sibling is
1013  						 * red, color it black
1014  						 * and rotate around
1015  						 * the current parent
1016  						 */
1017  						sibling->left->color = black;
1018  						rbtree_rotate_right(tree,
1019  								    curr_node->
1020  								    parent);
1021  					} else {
1022  						/* If the right child
1023  						 * of the sibling is
1024  						 * red, rotate around
1025  						 * the sibling, then
1026  						 * rotate around the
1027  						 * new sibling of our
1028  						 * current node
1029  						 */
1030  						rbtree_rotate_left(tree,
1031  								   sibling);
1032  						sibling =
1033  						    curr_node->parent->left;
1034  						rbtree_rotate_right(tree,
1035  								    sibling);
1036  					}
1037  
1038  					/* It is now safe to color the
1039  					 * parent black and to
1040  					 * terminate the fix process.
1041  					 */
1042  					if (curr_node->parent->parent)
1043  						curr_node->parent->parent->
1044  						    color =
1045  						    curr_node->parent->color;
1046  					curr_node->parent->color = black;
1047  					/* In order to stop the while loop */
1048  					curr_node = tree->root;
1049  				}
1050  			}
1051  		}
1052  	}
1053  
1054  	/* The root can always be colored black */
1055  	curr_node->color = black;
1056  }
1057  
1058  /* Traverse a red-black tree */
1059  
rbtree_traverse(rb_tree * tree,opr * op)1060  void rbtree_traverse(rb_tree * tree, opr * op)
1061  {
1062  	rbnode_traverse(tree->root, op);
1063  }
1064