1 /**
2  * Author: Emin Martinian
3  *
4  * Some repackaging by Perry Rapp
5  */
6 
7 #include<stdio.h>
8 #include<stdlib.h>
9 
10 #include "rbtree.h"
11 
12 /***********************************************************************
13  * Data Structures: tree & node
14  ***********************************************************************/
15 
16 /* Compare(a,b) should return 1 if *a > *b, -1 if *a < *b, and 0 otherwise */
17 /* Destroy(a) takes a pointer to whatever key might be and frees it accordingly */
18 struct rb_red_blk_tree {
19   KeyCompFuncType CompareFnc;
20   KeyInfoDestFuncType DestroyKeyInfoFnc;
21   /*  A sentinel is used for root and for nil.  These sentinels are */
22   /*  created when RbTreeCreate is caled.  root->left should always */
23   /*  point to the node which is the root of the tree.  nil points to a */
24   /*  node which should always be black but has aribtrary children and */
25   /*  parent and no key or info.  The point of using these sentinels is so */
26   /*  that the root and nil nodes do not require special cases in the code */
27   RBNODE root;
28   RBNODE nil;
29   void * param;
30   int count;
31 }; /* *RBTREE already declared in header */
32 
33 struct rb_red_blk_node {
34   RBKEY key;
35   RBVALUE info;
36   int red; /* if red=0 then the node is black */
37   RBNODE left;
38   RBNODE right;
39   RBNODE parent;
40 }; /* *RBNODE already declared in header */
41 
42 struct rb_red_blk_iter {
43 	RBTREE rbtree;
44 	RBKEY low;
45 	RBKEY high;
46 	RBNODE next; /* to give back at next call, NULL if done */
47 }; /* *RBITER already declared in header */
48 
49 /***********************************************************************
50  * Module data
51  ***********************************************************************/
52 
53 static void (*f_AssertFnc)(int assertion, const char* error) = 0;
54 static void * (*f_SafeMallocFnc)(size_t size) = 0;
55 
56 
57 /***********************************************************************
58  * Internal function declarations
59  ***********************************************************************/
60 
61 static void Assert(int assertion, char* error);
62 static RBNODE FindFirst(RBTREE tree, RBKEY low);
63 static void InorderTreePrint(RBTREE tree, RBNODE x, KeyPrintFuncType KeyPrintFunc, InfoPrintFuncType InfoPrintFunc);
64 static void LeftRotate(RBTREE tree, RBNODE x);
65 static void RbDeleteFixUp(RBTREE tree, RBNODE x);
66 static void RightRotate(RBTREE tree, RBNODE y);
67 static void * SafeMalloc(size_t size);
68 static int TreeCompare(RBTREE tree, RBKEY key1, RBKEY key2);
69 static void TreeDestHelper(RBTREE tree, RBNODE x);
70 static void TreeDestroyKeyInfo(RBTREE tree, RBKEY key, RBVALUE info);
71 static void TreeInsertHelp(RBTREE tree, RBNODE z);
72 static void TreePrintKey(RBTREE tree, RBKEY key, KeyPrintFuncType KeyPrintFunc);
73 static void TreePrintInfo(RBTREE tree, RBVALUE info, InfoPrintFuncType InfoPrintFunc);
74 
75 
76 /***********************************************************************
77  * FUNCTION:  RbInitModule
78  *
79  * Store pointers to necessary infrastructure functions
80  ***********************************************************************/
81 
82 void
RbInitModule(void (* AssertFunc)(int assertion,const char * error),void * (* SafeMallocFunc)(size_t size))83 RbInitModule (void (*AssertFunc)(int assertion, const char* error),
84                   void * (*SafeMallocFunc)(size_t size))
85 {
86 	f_AssertFnc = AssertFunc;
87 	f_SafeMallocFnc = SafeMallocFunc;
88 
89 	StackInitModule(AssertFunc, SafeMallocFunc);
90 }
91 
92 
93 /***********************************************************************/
94 /*  FUNCTION:  RbTreeCreate */
95 /**/
96 /*  INPUTS:  All the inputs are names of functions.  CompFunc takes to */
97 /*  void pointers to keys and returns 1 if the first arguement is */
98 /*  "greater than" the second.   DestFunc takes a pointer to a key and */
99 /*  destroys it in the appropriate manner when the node containing that */
100 /*  key is deleted.  InfoDestFunc is similiar to DestFunc except it */
101 /*  recieves a pointer to the info of a node and destroys it. */
102 /**/
103 /*  OUTPUT:  This function returns a pointer to the newly created */
104 /*  red-black tree. */
105 /**/
106 /*  Modifies Input: none */
107 /***********************************************************************/
108 
109 RBTREE
RbTreeCreate(void * param,KeyCompFuncType KeyCompFunc,KeyInfoDestFuncType KeyInfoDestFunc)110 RbTreeCreate (void * param, KeyCompFuncType KeyCompFunc, KeyInfoDestFuncType KeyInfoDestFunc)
111 {
112   RBTREE newTree;
113   RBNODE temp;
114 
115   newTree=(RBTREE) SafeMalloc(sizeof(*newTree));
116   newTree->param = param;
117   newTree->CompareFnc =  KeyCompFunc;
118   newTree->DestroyKeyInfoFnc = KeyInfoDestFunc;
119 
120   /*  see the comment in the rb_red_blk_tree structure in red_black_tree.h */
121   /*  for information on nil and root */
122   temp=newTree->nil= (RBNODE) SafeMalloc(sizeof(*temp));
123   temp->parent=temp->left=temp->right=temp;
124   temp->red=0;
125   temp->key=0;
126   temp=newTree->root= (RBNODE) SafeMalloc(sizeof(*temp));
127   temp->parent=temp->left=temp->right=newTree->nil;
128   temp->key=0;
129   temp->red=0;
130   return(newTree);
131 }
132 
133 /***********************************************************************/
134 /*  FUNCTION:  LeftRotate */
135 /**/
136 /*  INPUTS:  This takes a tree so that it can access the appropriate */
137 /*           root and nil pointers, and the node to rotate on. */
138 /**/
139 /*  OUTPUT:  None */
140 /**/
141 /*  Modifies Input: tree, x */
142 /**/
143 /*  EFFECTS:  Rotates as described in _Introduction_To_Algorithms by */
144 /*            Cormen, Leiserson, Rivest (Chapter 14).  Basically this */
145 /*            makes the parent of x be to the left of x, x the parent of */
146 /*            its parent before the rotation and fixes other pointers */
147 /*            accordingly. */
148 /***********************************************************************/
149 
150 static void
LeftRotate(RBTREE tree,RBNODE x)151 LeftRotate (RBTREE tree, RBNODE x)
152 {
153   RBNODE y;
154   RBNODE nil=tree->nil;
155 
156   /*  I originally wrote this function to use the sentinel for */
157   /*  nil to avoid checking for nil.  However this introduces a */
158   /*  very subtle bug because sometimes this function modifies */
159   /*  the parent pointer of nil.  This can be a problem if a */
160   /*  function which calls LeftRotate also uses the nil sentinel */
161   /*  and expects the nil sentinel's parent pointer to be unchanged */
162   /*  after calling this function.  For example, when RbDeleteFixUP */
163   /*  calls LeftRotate it expects the parent pointer of nil to be */
164   /*  unchanged. */
165 
166   y=x->right;
167   x->right=y->left;
168 
169   if (y->left != nil) y->left->parent=x; /* used to use sentinel here */
170   /* and do an unconditional assignment instead of testing for nil */
171 
172   y->parent=x->parent;
173 
174   /* instead of checking if x->parent is the root as in the book, we */
175   /* count on the root sentinel to implicitly take care of this case */
176   if( x == x->parent->left) {
177     x->parent->left=y;
178   } else {
179     x->parent->right=y;
180   }
181   y->left=x;
182   x->parent=y;
183 
184 #ifdef DEBUG_ASSERT
185   Assert(!tree->nil->red,"nil not red in LeftRotate");
186 #endif
187 }
188 
189 
190 /***********************************************************************/
191 /*  FUNCTION:  RighttRotate */
192 /**/
193 /*  INPUTS:  This takes a tree so that it can access the appropriate */
194 /*           root and nil pointers, and the node to rotate on. */
195 /**/
196 /*  OUTPUT:  None */
197 /**/
198 /*  Modifies Input?: tree, y */
199 /**/
200 /*  EFFECTS:  Rotates as described in _Introduction_To_Algorithms by */
201 /*            Cormen, Leiserson, Rivest (Chapter 14).  Basically this */
202 /*            makes the parent of x be to the left of x, x the parent of */
203 /*            its parent before the rotation and fixes other pointers */
204 /*            accordingly. */
205 /***********************************************************************/
206 
207 static void
RightRotate(RBTREE tree,RBNODE y)208 RightRotate (RBTREE tree, RBNODE y)
209 {
210   RBNODE x;
211   RBNODE nil=tree->nil;
212 
213   /*  I originally wrote this function to use the sentinel for */
214   /*  nil to avoid checking for nil.  However this introduces a */
215   /*  very subtle bug because sometimes this function modifies */
216   /*  the parent pointer of nil.  This can be a problem if a */
217   /*  function which calls LeftRotate also uses the nil sentinel */
218   /*  and expects the nil sentinel's parent pointer to be unchanged */
219   /*  after calling this function.  For example, when RbDeleteFixUP */
220   /*  calls LeftRotate it expects the parent pointer of nil to be */
221   /*  unchanged. */
222 
223   x=y->left;
224   y->left=x->right;
225 
226   if (nil != x->right)  x->right->parent=y; /*used to use sentinel here */
227   /* and do an unconditional assignment instead of testing for nil */
228 
229   /* instead of checking if x->parent is the root as in the book, we */
230   /* count on the root sentinel to implicitly take care of this case */
231   x->parent=y->parent;
232   if( y == y->parent->left) {
233     y->parent->left=x;
234   } else {
235     y->parent->right=x;
236   }
237   x->right=y;
238   y->parent=x;
239 
240 #ifdef DEBUG_ASSERT
241   Assert(!tree->nil->red,"nil not red in RightRotate");
242 #endif
243 }
244 
245 /***********************************************************************/
246 /*  FUNCTION:  TreeInsertHelp  */
247 /**/
248 /*  INPUTS:  tree is the tree to insert into and z is the node to insert */
249 /**/
250 /*  OUTPUT:  none */
251 /**/
252 /*  Modifies Input:  tree, z */
253 /**/
254 /*  EFFECTS:  Inserts z into the tree as if it were a regular binary tree */
255 /*            using the algorithm described in _Introduction_To_Algorithms_ */
256 /*            by Cormen et al.  This funciton is only intended to be called */
257 /*            by the RbTreeInsert function and not by the user */
258 /***********************************************************************/
259 
260 static void
TreeInsertHelp(RBTREE tree,RBNODE z)261 TreeInsertHelp (RBTREE tree, RBNODE z)
262 {
263   /*  This function should only be called by InsertRbTree (see above) */
264   RBNODE x;
265   RBNODE y;
266   RBNODE nil=tree->nil;
267 
268   z->left=z->right=nil;
269   y=tree->root;
270   x=tree->root->left;
271   while( x != nil) {
272     y=x;
273     if (0 < TreeCompare(tree, x->key,z->key)) { /* x.key > z.key */
274       x=x->left;
275     } else { /* x,key <= z.key */
276       x=x->right;
277     }
278   }
279   z->parent=y;
280   if ( (y == tree->root) ||
281        (0 < TreeCompare(tree, y->key,z->key))) { /* y.key > z.key */
282     y->left=z;
283   } else {
284     y->right=z;
285   }
286 
287 #ifdef DEBUG_ASSERT
288   Assert(!tree->nil->red,"nil not red in TreeInsertHelp");
289 #endif
290 }
291 
292 /*  Before calling Insert RbTree the node x should have its key set */
293 
294 /***********************************************************************/
295 /*  FUNCTION:  RbTreeInsert */
296 /**/
297 /*  INPUTS:  tree is the red-black tree to insert a node which has a key */
298 /*           pointed to by key and info pointed to by info.  */
299 /**/
300 /*  OUTPUT:  This function returns a pointer to the newly inserted node */
301 /*           which is guarunteed to be valid until this node is deleted. */
302 /*           What this means is if another data structure stores this */
303 /*           pointer then the tree does not need to be searched when this */
304 /*           is to be deleted. */
305 /**/
306 /*  Modifies Input: tree */
307 /**/
308 /*  EFFECTS:  Creates a node node which contains the appropriate key and */
309 /*            info pointers and inserts it into the tree. */
310 /***********************************************************************/
311 
312 RBNODE
RbTreeInsert(RBTREE tree,RBKEY key,RBVALUE info)313 RbTreeInsert (RBTREE tree, RBKEY key, RBVALUE info)
314 {
315   RBNODE y;
316   RBNODE x;
317   RBNODE newNode;
318 
319   ++tree->count;
320   x=(RBNODE) SafeMalloc(sizeof(*x));
321   x->key=key;
322   x->info=info;
323 
324   TreeInsertHelp(tree,x);
325   newNode=x;
326   x->red=1;
327   while(x->parent->red) { /* use sentinel instead of checking for root */
328     if (x->parent == x->parent->parent->left) {
329       y=x->parent->parent->right;
330       if (y->red) {
331 	x->parent->red=0;
332 	y->red=0;
333 	x->parent->parent->red=1;
334 	x=x->parent->parent;
335       } else {
336 	if (x == x->parent->right) {
337 	  x=x->parent;
338 	  LeftRotate(tree,x);
339 	}
340 	x->parent->red=0;
341 	x->parent->parent->red=1;
342 	RightRotate(tree,x->parent->parent);
343       }
344     } else { /* case for x->parent == x->parent->parent->right */
345       y=x->parent->parent->left;
346       if (y->red) {
347 	x->parent->red=0;
348 	y->red=0;
349 	x->parent->parent->red=1;
350 	x=x->parent->parent;
351       } else {
352 	if (x == x->parent->left) {
353 	  x=x->parent;
354 	  RightRotate(tree,x);
355 	}
356 	x->parent->red=0;
357 	x->parent->parent->red=1;
358 	LeftRotate(tree,x->parent->parent);
359       }
360     }
361   }
362   tree->root->left->red=0;
363   return(newNode);
364 
365 #ifdef DEBUG_ASSERT
366   Assert(!tree->nil->red,"nil not red in RbTreeInsert");
367   Assert(!tree->root->red,"root not red in RbTreeInsert");
368 #endif
369 }
370 
371 /***********************************************************************/
372 /*  FUNCTION:  RbTreeSuccessor  */
373 /**/
374 /*    INPUTS:  tree is the tree in question, and x is the node we want the */
375 /*             the successor of. */
376 /**/
377 /*    OUTPUT:  This function returns the successor of x or NULL if no */
378 /*             successor exists. */
379 /**/
380 /*    Modifies Input: none */
381 /**/
382 /*    Note:  uses the algorithm in _Introduction_To_Algorithms_ */
383 /***********************************************************************/
384 
385 RBNODE
RbTreeSuccessor(RBTREE tree,RBNODE x)386 RbTreeSuccessor (RBTREE tree, RBNODE x)
387 {
388   RBNODE y;
389   RBNODE nil=tree->nil;
390   RBNODE root=tree->root;
391 
392   if (nil != (y = x->right)) { /* assignment to y is intentional */
393     while(y->left != nil) { /* returns the minium of the right subtree of x */
394       y=y->left;
395     }
396     return(y);
397   } else {
398     y=x->parent;
399     while(x == y->right) { /* sentinel used instead of checking for nil */
400       x=y;
401       y=y->parent;
402     }
403     if (y == root) return(nil);
404     return(y);
405   }
406 }
407 
408 /***********************************************************************/
409 /*  FUNCTION:  RbTreePredecessor  */
410 /**/
411 /*    INPUTS:  tree is the tree in question, and x is the node we want the */
412 /*             the predecessor of. */
413 /**/
414 /*    OUTPUT:  This function returns the predecessor of x or NULL if no */
415 /*             predecessor exists. */
416 /**/
417 /*    Modifies Input: none */
418 /**/
419 /*    Note:  uses the algorithm in _Introduction_To_Algorithms_ */
420 /***********************************************************************/
421 
422 RBNODE
RbTreePredecessor(RBTREE tree,RBNODE x)423 RbTreePredecessor (RBTREE tree, RBNODE x)
424 {
425 	RBNODE y;
426 	RBNODE nil=tree->nil;
427 	RBNODE root=tree->root;
428 
429 	if (nil != (y = x->left)) { /* assignment to y is intentional */
430 		while(y->right != nil) { /* returns the maximum of the left subtree of x */
431 			y=y->right;
432 		}
433 		return(y);
434 	} else {
435 		y=x->parent;
436 		while(x == y->left) {
437 			if (y == root) return(nil);
438 			x=y;
439 			y=y->parent;
440 		}
441 		return(y);
442 	}
443 }
444 
445 /***********************************************************************/
446 /*  FUNCTION:  InorderTreePrint */
447 /**/
448 /*    INPUTS:  tree is the tree to print and x is the current inorder node */
449 /**/
450 /*    OUTPUT:  none  */
451 /**/
452 /*    EFFECTS:  This function recursively prints the nodes of the tree */
453 /*              inorder using the PrintKey and PrintInfo functions. */
454 /**/
455 /*    Modifies Input: none */
456 /**/
457 /*    Note:    This function should only be called from RBTreePrint */
458 /***********************************************************************/
459 
460 static void
InorderTreePrint(RBTREE tree,RBNODE x,KeyPrintFuncType KeyPrintFunc,InfoPrintFuncType InfoPrintFunc)461 InorderTreePrint (RBTREE tree, RBNODE x, KeyPrintFuncType KeyPrintFunc, InfoPrintFuncType InfoPrintFunc)
462 {
463   RBNODE nil=tree->nil;
464   RBNODE root=tree->root;
465   if (x != tree->nil) {
466     InorderTreePrint(tree,x->left, KeyPrintFunc, InfoPrintFunc);
467     printf("info=");
468     TreePrintInfo(tree, x->info, InfoPrintFunc);
469     printf("  key=");
470     TreePrintKey(tree, x->key, KeyPrintFunc);
471     printf("  l->key=");
472     if( x->left == nil) printf("NULL"); else TreePrintKey(tree, x->left->key, KeyPrintFunc);
473     printf("  r->key=");
474     if( x->right == nil) printf("NULL"); else TreePrintKey(tree, x->right->key, KeyPrintFunc);
475     printf("  p->key=");
476     if( x->parent == root) printf("NULL"); else TreePrintKey(tree, x->parent->key, KeyPrintFunc);
477     printf("  red=%i\n",x->red);
478     InorderTreePrint(tree, x->right, KeyPrintFunc, InfoPrintFunc);
479   }
480 }
481 
482 
483 /***********************************************************************/
484 /*  FUNCTION:  TreeDestHelper */
485 /**/
486 /*    INPUTS:  tree is the tree to destroy and x is the current node */
487 /**/
488 /*    OUTPUT:  none  */
489 /**/
490 /*    EFFECTS:  This function recursively destroys the nodes of the tree */
491 /*              postorder using the DestroyKey and DestroyInfo functions. */
492 /**/
493 /*    Modifies Input: tree, x */
494 /**/
495 /*    Note:    This function should only be called by RbTreeDestroy */
496 /***********************************************************************/
497 
498 static void
TreeDestHelper(RBTREE tree,RBNODE x)499 TreeDestHelper (RBTREE tree, RBNODE x)
500 {
501   RBNODE nil=tree->nil;
502   if (x != nil) {
503     TreeDestHelper(tree,x->left);
504     TreeDestHelper(tree,x->right);
505     TreeDestroyKeyInfo(tree, x->key, x->info);
506     free(x);
507   }
508 }
509 
510 
511 /***********************************************************************/
512 /*  FUNCTION:  RBTreeDestroy */
513 /**/
514 /*    INPUTS:  tree is the tree to destroy */
515 /**/
516 /*    OUTPUT:  none */
517 /**/
518 /*    EFFECT:  Destroys the key and frees memory */
519 /**/
520 /*    Modifies Input: tree */
521 /**/
522 /***********************************************************************/
523 
524 void
RbTreeDestroy(RBTREE tree)525 RbTreeDestroy (RBTREE tree)
526 {
527   TreeDestHelper(tree,tree->root->left);
528   free(tree->root);
529   free(tree->nil);
530   free(tree);
531 }
532 
533 
534 /***********************************************************************/
535 /*  FUNCTION:  RbTreePrint */
536 /**/
537 /*    INPUTS:  tree is the tree to print */
538 /**/
539 /*    OUTPUT:  none */
540 /**/
541 /*    EFFECT:  This function recursively prints the nodes of the tree */
542 /*             inorder using the PrintKey and PrintInfo functions. */
543 /**/
544 /*    Modifies Input: none */
545 /**/
546 /***********************************************************************/
547 
548 void
RbTreePrint(RBTREE tree,KeyPrintFuncType KeyPrintFunc,InfoPrintFuncType InfoPrintFunc)549 RbTreePrint (RBTREE tree, KeyPrintFuncType KeyPrintFunc, InfoPrintFuncType InfoPrintFunc)
550 {
551   InorderTreePrint(tree, tree->root->left, KeyPrintFunc, InfoPrintFunc);
552 }
553 
554 
555 /***********************************************************************/
556 /*  FUNCTION:  RbExactQuery */
557 /**/
558 /*    INPUTS:  tree is the tree to print and q is a pointer to the key */
559 /*             we are searching for */
560 /**/
561 /*    OUTPUT:  returns the a node with key equal to q.  If there are */
562 /*             multiple nodes with key equal to q this function returns */
563 /*             the one highest in the tree */
564 /**/
565 /*    Modifies Input: none */
566 /**/
567 /***********************************************************************/
568 
569 RBNODE
RbExactQuery(RBTREE tree,RBKEY q)570 RbExactQuery (RBTREE tree, RBKEY q)
571 {
572   RBNODE x=tree->root->left;
573   RBNODE nil=tree->nil;
574   int compVal;
575   if (x == nil) return(0);
576   compVal= TreeCompare(tree, x->key,(int*) q);
577   while(0 != compVal) {/*assignemnt*/
578     if (0 < compVal) { /* x->key > q */
579       x=x->left;
580     } else {
581       x=x->right;
582     }
583     if ( x == nil) return(0);
584     compVal = TreeCompare(tree, x->key,(int*) q);
585   }
586   return(x);
587 }
588 
589 
590 /***********************************************************************/
591 /*  FUNCTION:  RbDeleteFixUp */
592 /**/
593 /*    INPUTS:  tree is the tree to fix and x is the child of the spliced */
594 /*             out node in RBTreeDelete. */
595 /**/
596 /*    OUTPUT:  none */
597 /**/
598 /*    EFFECT:  Performs rotations and changes colors to restore red-black */
599 /*             properties after a node is deleted */
600 /**/
601 /*    Modifies Input: tree, x */
602 /**/
603 /*    The algorithm from this function is from _Introduction_To_Algorithms_ */
604 /***********************************************************************/
605 
606 static void
RbDeleteFixUp(RBTREE tree,RBNODE x)607 RbDeleteFixUp (RBTREE tree, RBNODE x)
608 {
609   RBNODE root=tree->root->left;
610   RBNODE w;
611 
612   while( (!x->red) && (root != x)) {
613     if (x == x->parent->left) {
614       w=x->parent->right;
615       if (w->red) {
616 	w->red=0;
617 	x->parent->red=1;
618 	LeftRotate(tree,x->parent);
619 	w=x->parent->right;
620       }
621       if ( (!w->right->red) && (!w->left->red) ) {
622 	w->red=1;
623 	x=x->parent;
624       } else {
625 	if (!w->right->red) {
626 	  w->left->red=0;
627 	  w->red=1;
628 	  RightRotate(tree,w);
629 	  w=x->parent->right;
630 	}
631 	w->red=x->parent->red;
632 	x->parent->red=0;
633 	w->right->red=0;
634 	LeftRotate(tree,x->parent);
635 	x=root; /* this is to exit while loop */
636       }
637     } else { /* the code below is has left and right switched from above */
638       w=x->parent->left;
639       if (w->red) {
640 	w->red=0;
641 	x->parent->red=1;
642 	RightRotate(tree,x->parent);
643 	w=x->parent->left;
644       }
645       if ( (!w->right->red) && (!w->left->red) ) {
646 	w->red=1;
647 	x=x->parent;
648       } else {
649 	if (!w->left->red) {
650 	  w->right->red=0;
651 	  w->red=1;
652 	  LeftRotate(tree,w);
653 	  w=x->parent->left;
654 	}
655 	w->red=x->parent->red;
656 	x->parent->red=0;
657 	w->left->red=0;
658 	RightRotate(tree,x->parent);
659 	x=root; /* this is to exit while loop */
660       }
661     }
662   }
663   x->red=0;
664 
665 #ifdef DEBUG_ASSERT
666   Assert(!tree->nil->red,"nil not black in RbDeleteFixUp");
667 #endif
668 }
669 
670 
671 /***********************************************************************/
672 /*  FUNCTION:  RbDeleteNode */
673 /**/
674 /*    INPUTS:  tree is the tree to delete node z from */
675 /**/
676 /*    OUTPUT:  none */
677 /**/
678 /*    EFFECT:  Deletes z from tree and frees the key and info of z */
679 /*             using DestoryKey and DestoryInfo.  Then calls */
680 /*             RBDeleteFixUp to restore red-black properties */
681 /**/
682 /*    Modifies Input: tree, z */
683 /**/
684 /*    The algorithm from this function is from _Introduction_To_Algorithms_ */
685 /***********************************************************************/
686 
687 void
RbDeleteNode(RBTREE tree,RBNODE z)688 RbDeleteNode (RBTREE tree, RBNODE z)
689 {
690   RBNODE y;
691   RBNODE x;
692   RBNODE nil=tree->nil;
693   RBNODE root=tree->root;
694 
695   y= ((z->left == nil) || (z->right == nil)) ? z : RbTreeSuccessor(tree,z);
696   x= (y->left == nil) ? y->right : y->left;
697   if (root == (x->parent = y->parent)) { /* assignment of y->p to x->p is intentional */
698     root->left=x;
699   } else {
700     if (y == y->parent->left) {
701       y->parent->left=x;
702     } else {
703       y->parent->right=x;
704     }
705   }
706   if (y != z) { /* y should not be nil in this case */
707 
708 #ifdef DEBUG_ASSERT
709     Assert( (y!=tree->nil),"y is nil in RBDelete\n");
710 #endif
711     /* y is the node to splice out and x is its child */
712 
713     if (!(y->red)) RbDeleteFixUp(tree,x);
714 
715 	--tree->count;
716     TreeDestroyKeyInfo(tree, z->key, z->info);
717     y->left=z->left;
718     y->right=z->right;
719     y->parent=z->parent;
720     y->red=z->red;
721     z->left->parent=z->right->parent=y;
722     if (z == z->parent->left) {
723       z->parent->left=y;
724     } else {
725       z->parent->right=y;
726     }
727     free(z);
728   } else {
729 	--tree->count;
730     TreeDestroyKeyInfo(tree, y->key, y->info);
731     if (!(y->red)) RbDeleteFixUp(tree,x);
732     free(y);
733   }
734 
735 #ifdef DEBUG_ASSERT
736   Assert(!tree->nil->red,"nil not black in RbDeleteNode");
737 #endif
738 }
739 
740 
741 /***********************************************************************/
742 /*  FUNCTION:  RbEnumerate */
743 /**/
744 /*    INPUTS:  tree is the tree to look for keys >= low */
745 /*             and <= high with respect to the Compare function */
746 /**/
747 /*    OUTPUT:  stack containing pointers to the nodes between [low,high] */
748 /**/
749 /*    Modifies Input: none */
750 /***********************************************************************/
751 
752 STKSTACK
RbEnumerate(RBTREE tree,RBKEY low,RBKEY high)753 RbEnumerate (RBTREE tree, RBKEY low, RBKEY high)
754 {
755 	STKSTACK enumResultStack=0;
756 	RBNODE nil=tree->nil;
757 	RBNODE x=tree->root->left;
758 	RBNODE lastBest=nil;
759 
760 	enumResultStack=StackCreate();
761 	while(nil != x) {
762 		if ( 0 < (TreeCompare(tree, x->key, high)) ) { /* x->key > high */
763 			x=x->left;
764 		} else {
765 			lastBest=x;
766 			x=x->right;
767 		}
768 	}
769 	while ( (lastBest != nil) && (0 >= TreeCompare(tree, low,lastBest->key))) {
770 		StackPush(enumResultStack,lastBest);
771 		lastBest=RbTreePredecessor(tree,lastBest);
772 	}
773 	return(enumResultStack);
774 }
775 
776 /***********************************************************************
777  * FUNCTION: RbTraverseDown
778  *
779  * Traverse tree area between low & high (including them)
780  * calling TraverseFunc for each node
781  * If TraverseFunc returns 0, stop traversal
782  *
783  ***********************************************************************/
784 
785 int
RbTraverseDown(RBTREE tree,RBKEY low,RBKEY high,void * param,TraverseFuncType TraverseFunc)786 RbTraverseDown (RBTREE tree, RBKEY low, RBKEY high, void *param, TraverseFuncType TraverseFunc)
787 {
788 	RBNODE nil=tree->nil;
789 	RBNODE x=tree->root->left;
790 	RBNODE lastBest=nil;
791 	int rtn=1;
792 
793 	/* Find starting location */
794 	while(nil != x) {
795 		if ( 0 < (TreeCompare(tree, x->key, high)) ) { /* x->key > high */
796 			x=x->left;
797 		} else {
798 			lastBest=x;
799 			x=x->right;
800 		}
801 	}
802 
803 	/* Now traverse, watching for ending location */
804 	while ( (lastBest != nil) && (0 >= TreeCompare(tree, low, lastBest->key))) {
805 
806 		rtn = (*TraverseFunc)(lastBest->key, lastBest->info, param);
807 		if (!rtn) return rtn;
808 		lastBest=RbTreePredecessor(tree,lastBest);
809 	}
810 	return rtn;
811 }
812 
813 /***********************************************************************
814  * FUNCTION: RbTraverseUp
815  *
816  * Traverse tree area between low & high (including them)
817  * calling TraverseFunc for each node
818  * If TraverseFunc returns 0, stop traversal
819  *
820  ***********************************************************************/
821 
822 int
RbTraverseUp(RBTREE tree,RBKEY low,RBKEY high,void * param,TraverseFuncType TraverseFunc)823 RbTraverseUp (RBTREE tree, RBKEY low, RBKEY high, void *param, TraverseFuncType TraverseFunc)
824 {
825 	RBNODE nil=tree->nil;
826 	RBNODE lastBest=nil;
827 	int rtn=1;
828 
829 	/* Find starting location */
830 	lastBest = FindFirst(tree, low);
831 
832 	/* Now traverse, watching for ending location */
833 	while ( (lastBest != nil) && (0 <= TreeCompare(tree, high, lastBest->key))) {
834 
835 		rtn = (*TraverseFunc)(lastBest->key, lastBest->info, param);
836 		if (!rtn) return rtn;
837 		lastBest=RbTreeSuccessor(tree,lastBest);
838 	}
839 	return rtn;
840 }
841 
842 RBNODE
RbTreeFirst(RBTREE tree)843 RbTreeFirst (RBTREE tree)
844 {
845 	return FindFirst(tree, NULL);
846 }
847 
848 RBITER
RbBeginIter(RBTREE tree,RBKEY low,RBKEY high)849 RbBeginIter (RBTREE tree, RBKEY low, RBKEY high)
850 {
851 	RBITER rbit = (RBITER)SafeMalloc(sizeof(*rbit));
852 	rbit->rbtree = tree;
853 	rbit->low = low;
854 	rbit->high = high;
855 	rbit->next = FindFirst(tree, low);
856 	return rbit;
857 }
858 
859 /***********************************************************************
860  * FUNCTION: FindFirst
861  *
862  * Find lowest key in tree no lower than low
863  *
864  ***********************************************************************/
865 static RBNODE
FindFirst(RBTREE tree,RBKEY low)866 FindFirst (RBTREE tree, RBKEY low)
867 {
868 	RBNODE nil=tree->nil;
869 	RBNODE x=tree->root->left;
870 	RBNODE lastBest=nil;
871 
872 	/* Find starting location */
873 	while(nil != x) {
874 		if ( low && 0 > (TreeCompare(tree, x->key, low)) ) { /* x->key < low */
875 			x=x->right;
876 		} else {
877 			lastBest=x;
878 			x=x->left;
879 		}
880 	}
881 	return lastBest;
882 }
883 
884 /***********************************************************************
885  * FUNCTION: FindLast
886  *
887  * Find highest key in tree no higher than high
888  *
889  ***********************************************************************/
890 static RBNODE
FindLast(RBTREE tree,RBKEY high)891 FindLast (RBTREE tree, RBKEY high)
892 {
893 	RBNODE nil=tree->nil;
894 	RBNODE x=tree->root->left;
895 	RBNODE lastBest=nil;
896 
897 	/* Find starting location */
898 	while(nil != x) {
899 		if ( high && 0 < (TreeCompare(tree, x->key, high)) ) { /* x->key > high */
900 			x=x->left;
901 		} else {
902 			lastBest=x;
903 			x=x->right;
904 		}
905 	}
906 	return lastBest;
907 }
908 
909 int
RbNext(RBITER rbit,RBKEY * pkey,RBVALUE * pinfo)910 RbNext (RBITER rbit, RBKEY * pkey, RBVALUE * pinfo)
911 {
912 	RBNODE next = rbit->next;
913 	RBNODE nil = rbit->rbtree->nil;
914 	if (next == nil) return 0;
915 	rbit->next = RbTreeSuccessor(rbit->rbtree, next);
916 	if (rbit->high) {
917 		if (0 < TreeCompare(rbit->rbtree, next->key, rbit->high)) { /* next->key > rbit->high */
918 			rbit->next = rbit->rbtree->nil;
919 			return 0;
920 		}
921 	}
922 	*pkey = next->key;
923 	*pinfo = next->info;
924 	return 1;
925 }
926 
927 void
RbEndIter(RBITER rbiter)928 RbEndIter (RBITER rbiter)
929 {
930 	free(rbiter);
931 }
932 
933 int
RbIsNil(RBTREE tree,RBNODE node)934 RbIsNil (RBTREE tree, RBNODE node)
935 {
936 	return tree->nil == node;
937 }
938 
939 RBNODE
RbGetNil(RBTREE tree)940 RbGetNil (RBTREE tree)
941 {
942 	Assert(tree!=0, "RbGetNil(NULL) called");
943 	return tree->nil;
944 }
945 
946 
947 RBKEY
RbGetKey(RBNODE node)948 RbGetKey (RBNODE node)
949 {
950 	Assert(node!=0, "RbGetKey(NULL) called");
951 	return node->key;
952 }
953 
954 RBVALUE
RbGetInfo(RBNODE node)955 RbGetInfo(RBNODE node)
956 {
957 	Assert(node!=0, "RbGetInfo(NULL) called");
958 	return node->info;
959 }
960 RBVALUE
RbSetInfo(RBNODE node,RBVALUE info)961 RbSetInfo (RBNODE node, RBVALUE info)
962 {
963 	RBVALUE old;
964 	Assert(node!=0, "RbSetInfo(NULL,) called");
965 	old = node->info;
966 	node->info = info;
967 	return old;
968 }
969 
970 /***********************************************************************
971  * Wrappers to call the client-supplied utility functions
972  ***********************************************************************/
973 
974 static int
TreeCompare(RBTREE tree,RBKEY key1,RBKEY key2)975 TreeCompare (RBTREE tree, RBKEY key1, RBKEY key2)
976 {
977 	Assert(tree && tree->CompareFnc, "Bad argument to TreeCompare");
978 	return (*tree->CompareFnc)(key1, key2);
979 }
980 
981 static void
TreeDestroyKeyInfo(RBTREE tree,RBKEY key,RBVALUE info)982 TreeDestroyKeyInfo (RBTREE tree, RBKEY key, RBVALUE info)
983 {
984 	Assert(tree && tree->DestroyKeyInfoFnc, "Bad argument to TreeDestroyKeyInfo");
985 	(*tree->DestroyKeyInfoFnc)(tree->param, key, info);
986 }
987 static void
TreePrintKey(RBTREE tree,RBKEY key,KeyPrintFuncType KeyPrintFunc)988 TreePrintKey (RBTREE tree, RBKEY key, KeyPrintFuncType KeyPrintFunc)
989 {
990 	Assert(tree && KeyPrintFunc, "Bad argument to TreePrintKey");
991 	(*KeyPrintFunc)(key);
992 }
993 static void
TreePrintInfo(RBTREE tree,RBVALUE info,InfoPrintFuncType InfoPrintFunc)994 TreePrintInfo (RBTREE tree, RBVALUE info, InfoPrintFuncType InfoPrintFunc)
995 {
996 	Assert(tree && InfoPrintFunc, "Bad argument to TreePrintInfo");
997 	(*InfoPrintFunc)(info);
998 }
999 static void
Assert(int assertion,char * error)1000 Assert (int assertion, char* error)
1001 {
1002 	if (!f_AssertFnc) return;
1003 	(*f_AssertFnc)(assertion, error);
1004 }
1005 static void *
SafeMalloc(size_t size)1006 SafeMalloc (size_t size)
1007 {
1008 	return (*f_SafeMallocFnc)(size);
1009 }
1010 
1011 /***********************************************************************
1012  *  NullFunction does nothing it is included so that it can be passed
1013  *  as a function to RBTreeCreate when no other suitable function has
1014  *  been defined
1015  ***********************************************************************/
1016 
1017 void
NullFunction(void * junk)1018 NullFunction(void * junk)
1019 {
1020 	junk=junk; /* unused */
1021 }
1022 int
RbGetCount(RBTREE rbtree)1023 RbGetCount (RBTREE rbtree)
1024 {
1025 	return rbtree->count;
1026 }
1027