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