Commit ef6ccfbcbe379737fc4b3d52388f28f8d6192806

Authored by Georg Hopp
1 parent 52755ca9

rbtree insert and delete now as one function and working as expected...still has…

… to be checked on sideeffects.
Showing 1 changed file with 153 additions and 180 deletions
@@ -89,7 +89,7 @@ sibling(struct element * node) @@ -89,7 +89,7 @@ sibling(struct element * node)
89 } 89 }
90 90
91 /* 91 /*
92 - * rotations...also needed for rb handling. 92 + * tree modifications...needed for rb handling.
93 */ 93 */
94 void 94 void
95 rotateLeft(struct element ** tree, struct element * node) 95 rotateLeft(struct element ** tree, struct element * node)
@@ -139,6 +139,23 @@ rotateRight(struct element ** tree, struct element * node) @@ -139,6 +139,23 @@ rotateRight(struct element ** tree, struct element * node)
139 node->parent = leftChild; 139 node->parent = leftChild;
140 } 140 }
141 141
  142 +void
  143 +replaceNode(struct element * node1, struct element * node2)
  144 +{
  145 + if (NULL != node1->parent) {
  146 + if (node1 == node1->parent->left) {
  147 + node1->parent->left = node2;
  148 + } else {
  149 + node1->parent->right = node2;
  150 + }
  151 + }
  152 +
  153 + if (NULL != node2) {
  154 + node2->parent = node1->parent;
  155 + }
  156 +}
  157 +
  158 +
142 /** 159 /**
143 * insert element in tree 160 * insert element in tree
144 */ 161 */
@@ -269,7 +286,10 @@ struct element * deleteOneChild(struct element **, struct element *); @@ -269,7 +286,10 @@ struct element * deleteOneChild(struct element **, struct element *);
269 struct element * 286 struct element *
270 deleteElement(struct element ** tree, int data) 287 deleteElement(struct element ** tree, int data)
271 { 288 {
272 - struct element * node = *tree; 289 + struct element * node = *tree;
  290 + struct element * del_node;
  291 + struct element * child;
  292 + struct element * s;
273 293
274 // find the relevant node and it's parent 294 // find the relevant node and it's parent
275 while (NULL != node && node->data != data) { 295 while (NULL != node && node->data != data) {
@@ -285,27 +305,150 @@ deleteElement(struct element ** tree, int data) @@ -285,27 +305,150 @@ deleteElement(struct element ** tree, int data)
285 return node; 305 return node;
286 } 306 }
287 307
  308 + del_node = node;
  309 +
288 // now our cases follows...the first one is the same as with 310 // now our cases follows...the first one is the same as with
289 - // simple binary search trees. 311 + // simple binary search trees. Two non null children.
290 312
291 // case 1: two children 313 // case 1: two children
292 if (NULL != node->left && NULL != node->right) { 314 if (NULL != node->left && NULL != node->right) {
293 struct element * successor = findInOrderSuccessor(node); 315 struct element * successor = findInOrderSuccessor(node);
294 316
295 node->data = successor->data; 317 node->data = successor->data;
296 - node = successor; 318 + del_node = node = successor;
  319 + }
  320 +
  321 + // delete and rb rebalance...
  322 + while(1) {
  323 + // Precondition: n has at most one non-null child.
  324 + child = (NULL == node->right) ? node->left : node->right;
  325 + replaceNode(node, child);
  326 +
  327 + // delete one child case
  328 + // TODO this is overly complex as simply derived from the function...
  329 + // maybe this can be simplified. Maybe not...check.
  330 + if (node->color == rbBlack) {
  331 + if (NULL != child && child->color == rbRed) {
  332 + child->color = rbBlack;
  333 + // done despite modifying tree itself if neccessary..
  334 + break;
  335 + } else {
  336 + if (NULL == node->parent){
  337 + *tree = 0x0;
  338 + }
  339 + node = child;
  340 + }
  341 + } else {
  342 + if (NULL == node->parent){
  343 + *tree = 0x0;
  344 + }
  345 + break;
  346 + }
  347 +
  348 + // case 1
  349 + if (NULL == node || NULL == node->parent) {
  350 + // done again
  351 + break;
  352 + }
  353 +
  354 + // case 2
  355 + s = sibling(node);
  356 +
  357 + if (NULL != s && s->color == rbRed) {
  358 + node->parent->color = rbRed;
  359 + s->color = rbBlack;
  360 +
  361 + if (node == node->parent->left) {
  362 + rotateLeft(tree, node->parent);
  363 + } else {
  364 + rotateRight(tree, node->parent);
  365 + }
  366 + }
  367 +
  368 + // case 3 / 4
  369 + if (NULL == s || ((s->color == rbBlack) &&
  370 + (s->left->color == rbBlack) &&
  371 + (s->right->color == rbBlack))) {
  372 +
  373 + if (NULL != s) {
  374 + s->color = rbRed;
  375 + }
  376 +
  377 + if (node->parent->color == rbBlack) {
  378 + // case 3
  379 + node = node->parent;
  380 + continue;
  381 + } else {
  382 + // case 4
  383 + node->parent->color = rbBlack;
  384 + // and done again...
  385 + break;
  386 + }
  387 + } else {
  388 + // done...
  389 + break;
  390 + }
  391 +
  392 +
  393 + // case 5
  394 + if (NULL != s && s->color == rbBlack) {
  395 + // this if statement is trivial,
  396 + // due to case 2 (even though case 2 changed the sibling to a
  397 + // sibling's child,
  398 + // the sibling's child can't be red, since no red parent can
  399 + // have a red child).
  400 + //
  401 + // the following statements just force the red to be on the
  402 + // left of the left of the parent,
  403 + // or right of the right, so case 6 will rotate correctly.
  404 + if ((node == node->parent->left) &&
  405 + (s->right->color == rbBlack) &&
  406 + (s->left->color == rbRed)) {
  407 +
  408 + // this last test is trivial too due to cases 2-4.
  409 + s->color = rbRed;
  410 + s->left->color = rbBlack;
  411 +
  412 + rotateRight(tree, s);
  413 + } else if ((node == node->parent->right) &&
  414 + (s->left->color == rbBlack) &&
  415 + (s->right->color == rbRed)) {
  416 + // this last test is trivial too due to cases 2-4.
  417 + s->color = rbRed;
  418 + s->right->color = rbBlack;
  419 +
  420 + rotateLeft(tree, s);
  421 + }
  422 + }
  423 +
  424 + // case 6
  425 + s->color = node->parent->color;
  426 + node->parent->color = rbBlack;
  427 +
  428 + if (node == node->parent->left) {
  429 + s->right->color = rbBlack;
  430 + rotateLeft(tree, node->parent);
  431 + } else {
  432 + s->left->color = rbBlack;
  433 + rotateRight(tree, node->parent);
  434 + }
  435 +
  436 + // done...
  437 + break;
297 } 438 }
  439 +
  440 + //deleteOneChild(tree, node);
298 441
299 - return deleteOneChild(tree, node); 442 + return del_node;
300 } 443 }
301 444
302 445
303 void 446 void
304 -traverse(struct element * tree, void (*cb)(int, int)) 447 +traverse(struct element * tree, void (*cb)(int, int, enum rbColor))
305 { 448 {
306 struct element * previous = tree; 449 struct element * previous = tree;
307 struct element * node = tree; 450 struct element * node = tree;
308 - int depth = 1; 451 + int depth = 1;
309 452
310 /* 453 /*
311 * I think this has something like O(n+log(n)) on a ballanced 454 * I think this has something like O(n+log(n)) on a ballanced
@@ -329,7 +472,7 @@ traverse(struct element * tree, void (*cb)(int, int)) @@ -329,7 +472,7 @@ traverse(struct element * tree, void (*cb)(int, int))
329 * If there are no more elements to the left or we 472 * If there are no more elements to the left or we
330 * came from the left, process data. 473 * came from the left, process data.
331 */ 474 */
332 - cb(node->data, depth); 475 + cb(node->data, depth, node->color);
333 previous = node; 476 previous = node;
334 477
335 if (NULL != node->right) { 478 if (NULL != node->right) {
@@ -350,184 +493,16 @@ traverse(struct element * tree, void (*cb)(int, int)) @@ -350,184 +493,16 @@ traverse(struct element * tree, void (*cb)(int, int))
350 } 493 }
351 } 494 }
352 495
353 -void printElement(int data, int depth) 496 +void printElement(int data, int depth, enum rbColor color)
354 { 497 {
355 int i; 498 int i;
356 499
357 - printf("%02d(%02d)", data, depth); 500 + printf("%s %02d(%02d)", (color==rbRed)?"R":"B", data, depth);
358 for (i=0; i<depth; i++) printf("-"); 501 for (i=0; i<depth; i++) printf("-");
359 puts(""); 502 puts("");
360 } 503 }
361 504
362 505
363 -void  
364 -replaceNode(struct element * node1, struct element * node2)  
365 -{  
366 - if (NULL != node1->parent) {  
367 - if (node1 == node1->parent->left) {  
368 - node1->parent->left = node2;  
369 - } else {  
370 - node1->parent->right = node2;  
371 - }  
372 - }  
373 -  
374 - if (NULL != node2) {  
375 - node2->parent = node1->parent;  
376 - }  
377 -}  
378 -  
379 -void  
380 -deleteCase6(struct element ** tree, struct element * node)  
381 -{  
382 - struct element * s = sibling(node);  
383 -  
384 - s->color = node->parent->color;  
385 - node->parent->color = rbBlack;  
386 -  
387 - if (node == node->parent->left) {  
388 - s->right->color = rbBlack;  
389 - rotateLeft(tree, node->parent);  
390 - } else {  
391 - s->left->color = rbBlack;  
392 - rotateRight(tree, node->parent);  
393 - }  
394 -}  
395 -  
396 -void  
397 -deleteCase5(struct element ** tree, struct element * node)  
398 -{  
399 - struct element * s = sibling(node);  
400 -  
401 - if (NULL != s && s->color == rbBlack) {  
402 - /*  
403 - * this if statement is trivial,  
404 - * due to case 2 (even though case 2 changed the sibling to a  
405 - * sibling's child,  
406 - * the sibling's child can't be red, since no red parent can  
407 - * have a red child).  
408 - */  
409 - /*  
410 - * the following statements just force the red to be on the  
411 - * left of the left of the parent,  
412 - * or right of the right, so case six will rotate correctly.  
413 - */  
414 - if ((node == node->parent->left) &&  
415 - (s->right->color == rbBlack) &&  
416 - (s->left->color == rbRed)) {  
417 -  
418 - /* this last test is trivial too due to cases 2-4. */  
419 - s->color = rbRed;  
420 - s->left->color = rbBlack;  
421 -  
422 - rotateRight(tree, s);  
423 - } else if ((node == node->parent->right) &&  
424 - (s->left->color == rbBlack) &&  
425 - (s->right->color == rbRed)) {  
426 - /*  
427 - * this last test is trivial too due to cases 2-4.  
428 - */  
429 - s->color = rbRed;  
430 - s->right->color = rbBlack;  
431 -  
432 - rotateLeft(tree, s);  
433 - }  
434 - }  
435 -  
436 - deleteCase6(tree, node);  
437 -}  
438 -  
439 -void  
440 -deleteCase4(struct element ** tree, struct element * node)  
441 -{  
442 - struct element * s = sibling(node);  
443 -  
444 - if ((node->parent->color == rbRed) &&  
445 - (NULL == s || ((s->color == rbBlack) &&  
446 - (s->left->color == rbBlack) &&  
447 - (s->right->color == rbBlack)))) {  
448 - if (NULL != s) {  
449 - s->color = rbRed;  
450 - }  
451 - node->parent->color = rbBlack;  
452 - } else {  
453 - deleteCase5(tree, node);  
454 - }  
455 -}  
456 -  
457 -void deleteCase1(struct element **, struct element *);  
458 -  
459 -void  
460 -deleteCase3(struct element ** tree, struct element * node)  
461 -{  
462 - struct element * s = sibling(node);  
463 -  
464 - if ((node->parent->color == rbBlack) &&  
465 - (NULL == s || ((s->color == rbBlack) &&  
466 - (s->left->color == rbBlack) &&  
467 - (s->right->color == rbBlack)))) {  
468 - if (NULL != s) {  
469 - s->color = rbRed;  
470 - }  
471 - deleteCase1(tree, node->parent);  
472 - } else {  
473 - deleteCase4(tree, node);  
474 - }  
475 -}  
476 -  
477 -void  
478 -deleteCase2(struct element ** tree, struct element * node)  
479 -{  
480 - struct element * s = sibling(node);  
481 -  
482 - if (NULL != s && s->color == rbRed) {  
483 - node->parent->color = rbRed;  
484 - s->color = rbBlack;  
485 -  
486 - if (node == node->parent->left) {  
487 - rotateLeft(tree, node->parent);  
488 - } else {  
489 - rotateRight(tree, node->parent);  
490 - }  
491 - }  
492 -  
493 - deleteCase3(tree, node);  
494 -}  
495 -  
496 -void  
497 -deleteCase1(struct element ** tree, struct element * node)  
498 -{  
499 - if (NULL != node && NULL != node->parent) {  
500 - deleteCase2(tree, node);  
501 - }  
502 -}  
503 -  
504 -struct element *  
505 -deleteOneChild(struct element ** tree, struct element * node)  
506 -{  
507 - /*  
508 - * Precondition: n has at most one non-null child.  
509 - */  
510 - struct element * child = (NULL == node->right) ? node->left : node->right;  
511 -  
512 - replaceNode(node, child);  
513 -  
514 - if (node->color == rbBlack) {  
515 - if (NULL != child && child->color == rbRed) {  
516 - child->color = rbBlack;  
517 - } else {  
518 - deleteCase1(tree, child);  
519 - }  
520 - }  
521 -  
522 - if (NULL == node->parent){  
523 - *tree = 0x0;  
524 - }  
525 -  
526 - return node;  
527 -}  
528 -  
529 -  
530 -  
531 /** 506 /**
532 * ======================================================================= 507 * =======================================================================
533 */ 508 */
@@ -548,7 +523,6 @@ main(int argc, char * argv[]) @@ -548,7 +523,6 @@ main(int argc, char * argv[])
548 puts("traverse"); 523 puts("traverse");
549 traverse(root, printElement); 524 traverse(root, printElement);
550 525
551 - /*  
552 free(deleteElement(&root, 8)); 526 free(deleteElement(&root, 8));
553 puts("traverse"); 527 puts("traverse");
554 traverse(root, printElement); 528 traverse(root, printElement);
@@ -580,7 +554,6 @@ main(int argc, char * argv[]) @@ -580,7 +554,6 @@ main(int argc, char * argv[])
580 free(deleteElement(&root, 12)); 554 free(deleteElement(&root, 12));
581 puts("traverse"); 555 puts("traverse");
582 traverse(root, printElement); 556 traverse(root, printElement);
583 - */  
584 557
585 return 0; 558 return 0;
586 } 559 }
Please register or login to post a comment