35template <
typename T,
typename S =
int>
class RBTree :
public BinTree<T,S> {
43 this->_colorSpace = 0;
51 virtual bool isNull()
const {
return false; }
66 int lvl = this->
level();
68 for (
int i = 1; i <= lvl; i++) {
70 if (!this->
isRoot()) std::cout <<
" |";
74 if (this->
childType() != 0) std::cout <<
" |";
75 else std::cout <<
" ";
83 for (
int i = 0; i < this->
colorCount(); i++) std::cout <<
"[";
85 for (
int i = 0; i < this->
colorCount(); i++) std::cout <<
"]";
88 std::cout << std::endl;
95 if (l->
isNull() && r->isNull()) {
97 }
else if (!l->
isNull() && !r->isNull()) {
139 unsigned char _colorSpace;
153 virtual bool isNull()
const {
return true; }
174 virtual bool isNull()
const {
return false; }
212 else if (node->
isNull())
return 0;
214 int result = this->
_st.push(node);
263 if (!node)
return 101;
274 virtual void print(
bool printNullNodes) {
275 std::cout << std::endl;
276 this->
print(this->
root(), printNullNodes);
277 std::cout << std::endl;
311 virtual void * createNode() {
312 return new RBNodeNonnull;
318 virtual int deleteNode(
typename BinTree<T,S>::BinNode * bnode) {
319 RBNode * node = (RBNode *) bnode;
320 bool isRoot = node->isRoot();
324 RBNode *
max = (RBNode *) this->
maxNode(node->left());
327 RBNode * dbNode = (RBNode *)
max->
left();
336 if (!dbNode) result = 107;
338 if (dbNode->colorCount() == 2) {
339 result = this->balanceRemoval(dbNode);
348 if (RBTree<T,S>::isNodeRed(this->
root())) {
356 if (node->left()->isNull()) {
357 RBNode * l = (RBNode *) node->left();
362 if ((node->right())->isNull()) {
363 RBNode * r = (RBNode *) node->right();
377 static bool isNodeBlack(
const RBNode * node) {
378 if (!node)
return true;
379 else if (node->isNull())
return true;
383 static bool isNodeRed(
const RBNode * node) {
384 if (!node)
return false;
385 else if (node->isNull())
return false;
397 int insert(RBNode * newNode, RBNode * parent) {
399 if (result == 0) result = this->balanceInsertion(newNode);
403 virtual bool canNewNodeTakeNewLocation(
typename BinTree<T,S>::BinNode ** newLocation) {
404 RBNode ** rbLocation = (RBNode **) newLocation;
406 if (!(*rbLocation)->isNull())
return false;
416 int balanceInsertion(RBNode * node) {
421 }
else if (RBTree<T>::isNodeBlack(node)) {
423 }
else if (RBTree<T>::isNodeBlack((RBNode *) node->_parent)) {
425 }
else if (RBTree<T>::isNodeRed((RBNode *) node->_parent)) {
427 if (RBTree<T>::isNodeBlack(node->pibling())) {
428 RBNode * parent = (RBNode *) node->_parent;
429 unsigned char rcase = this->rotationCase(node);
431 if ((rcase == ROTATION_CASE_RR) || (rcase == ROTATION_CASE_LL)) {
432 if ((tmp = (RBNode *) node->_parent)) {
436 if ((tmp = node->grandParent())) {
441 int result = this->rotate(node, rcase);
444 if ((rcase == ROTATION_CASE_RL) || (rcase == ROTATION_CASE_LR)) {
445 if ((tmp = (RBNode *) parent->_parent)) {
449 if ((tmp = parent->grandParent())) {
456 if (rcase == ROTATION_CASE_LR) {
457 result = this->rotate(parent, ROTATION_CASE_LL);
458 }
else if (rcase == ROTATION_CASE_RL) {
459 result = this->rotate(parent, ROTATION_CASE_RR);
465 }
else if (RBTree<T>::isNodeRed(node->pibling())) {
470 if ((tmp = node->pibling()) != NULL) {
474 if ((tmp = node->grandParent()) != NULL) {
478 return this->balanceInsertion(tmp);
494 int balanceRemoval(RBNode * node) {
496 RBNode * sibling = node->sibling();
497 RBNode * parent = (RBNode *) node->_parent;
498 bool doCaseSix =
false;
500 if ((node->colorCount() < 2) && !RBTree<T>::isNodeBlack(node)) {
506 if (node->isRoot()) {
507 node->setColorCount(1);
510 }
else if (RBTree<T>::isNodeBlack(sibling)) {
511 unsigned char rcase = 0;
512 RBNode * childOne = NULL, * childTwo = NULL;
513 char sibChildType = sibling->childType();
514 switch (sibChildType) {
516 childOne = (RBNode *) sibling->right();
517 childTwo = (RBNode *) sibling->left();
520 childOne = (RBNode *) sibling->left();
521 childTwo = (RBNode *) sibling->right();
530 if (RBTree<T>::isNodeBlack(parent)) {
532 if (RBTree<T>::isNodeRed(childOne) && RBTree<T>::isNodeBlack(childTwo)) {
533 switch (childOne->childType()) {
535 rcase = ROTATION_CASE_RL;
538 rcase = ROTATION_CASE_LR;
548 result = this->rotate(childOne, rcase);
551 result = this->balanceRemoval(node);
555 }
else if (RBTree<T>::isNodeRed(childTwo)) {
559 node->setColorCount(1);
560 parent->setColorCount(2);
563 result = this->balanceRemoval(parent);
567 }
else if (RBTree<T>::isNodeRed(parent)) {
569 if (RBTree<T>::isNodeBlack(childOne) && RBTree<T>::isNodeBlack(childTwo)) {
572 node->setColorCount(1);
575 }
else if (RBTree<T>::isNodeRed(childTwo)) {
585 if (!result && doCaseSix) {
586 switch (childTwo->childType()) {
588 rcase = ROTATION_CASE_LL;
591 rcase = ROTATION_CASE_RR;
598 sibling->setColor(parent->color());
600 node->setColorCount(1);
602 result = this->rotate(childTwo, rcase);
606 }
else if (RBTree<T>::isNodeRed(sibling)) {
607 if (RBTree<T>::isNodeBlack(sibling->left()) && RBTree<T>::isNodeBlack(sibling->right())) {
608 unsigned char rcase = 0;
609 RBNode * child = NULL;
610 switch (sibling->childType()) {
612 rcase = ROTATION_CASE_LL;
613 child = sibling->left();
616 rcase = ROTATION_CASE_RR;
617 child = sibling->right();
626 result = this->rotate((RBNode *) child, rcase);
630 result = this->balanceRemoval(node);
644 virtual int replaceNodeWithTheOnlyChild(
typename BinTree<T,S>::BinNode * bnode) {
646 typename BinTree<T,S>::BinNode * rep = NULL;
647 RBNode * node = (RBNode *) bnode;
649 if (node->childCount() != 1) {
654 if (!((RBNode *) node->left())->isNull()) {
657 }
else if (!((RBNode *) node->right())->isNull()) {
659 node->setRight(NULL);
667 result = this->replaceNodeWithNode(node, rep);
676 virtual int replaceNodeWithNode(
typename BinTree<T,S>::BinNode * bnode,
typename BinTree<T,S>::BinNode * breplacement) {
677 RBNode * node = (RBNode *) bnode;
678 RBNode * replacement = (RBNode *) breplacement;
681 replacement =
new RBNodeNull;
688 unsigned char currCount = replacement->colorCount();
689 replacement->setColorCount(++currCount);
698 static const unsigned char ROTATION_CASE_LL = 1;
699 static const unsigned char ROTATION_CASE_LR = 2;
700 static const unsigned char ROTATION_CASE_RR = 3;
701 static const unsigned char ROTATION_CASE_RL = 4;
712 unsigned char rotationCase(RBNode * node) {
714 else if (RBTree<T>::isNodeBlack(node))
return 0;
715 else if (node->isRoot())
return 0;
716 else if (node->childType() == 0)
return 0;
720 switch (node->childType()) {
723 return ROTATION_CASE_LL;
726 return ROTATION_CASE_LR;
731 switch (node->childType()) {
734 return ROTATION_CASE_RL;
737 return ROTATION_CASE_RR;
754 int rotate(RBNode * node,
unsigned char rotationCase) {
758 RBNode * grandparent = node->grandParent();
760 const unsigned char ll = ROTATION_CASE_LL;
761 const unsigned char lr = ROTATION_CASE_LR;
762 const unsigned char rr = ROTATION_CASE_RR;
763 const unsigned char rl = ROTATION_CASE_RL;
764 unsigned char rcase = rotationCase;
765 RBNode ** newLocation = NULL;
769 if ((rcase == ll) || (rcase == rr)) {
770 childType = parent->childType();
772 }
else if ((rcase == lr) || (rcase == rl)) {
773 childType = node->childType();
781 tmp->setLeft(
new RBNodeNull);
785 this->
setNodeParent(tmp->left(), (
typename BinTree<T,S>::BinNode *) tmp);
788 tmp->setRight(
new RBNodeNull);
792 this->
setNodeParent(tmp->right(), (
typename BinTree<T,S>::BinNode *) tmp);
801 if ((rcase == ll) || (rcase == rr)) {
810 (
typename BinTree<T,S>::BinNode *) grandparent
830 tmp = (RBNode *) parent->right();
831 newLocation = (RBNode **) parent->rightAddr();
833 tmp = (RBNode *) parent->left();
834 newLocation = (RBNode **) parent->leftAddr();
839 this->
setNodeParent(grandparent, (
typename BinTree<T,S>::BinNode *) parent);
840 *newLocation = grandparent;
842 this->
setNodeLocation(grandparent, (
typename BinTree<T,S>::BinNode **) newLocation);
846 if (!tmp->isNull()) {
848 this->
setNodeParent(tmp, (
typename BinTree<T,S>::BinNode *) grandparent);
850 newLocation = (RBNode **) grandparent->leftAddr();
852 newLocation = (RBNode **) grandparent->rightAddr();
855 }
else if ((rcase == lr) || (rcase == rl)) {
876 this->
setNodeParent((
typename BinTree<T,S>::BinNode *) parent, NULL);
878 this->
setNodeLocation((
typename BinTree<T,S>::BinNode *) parent, NULL);
882 tmp = (RBNode *) node->left();
883 newLocation = (RBNode **) node->leftAddr();
885 tmp = (RBNode *) node->right();
886 newLocation = (RBNode **) node->rightAddr();
891 this->
setNodeParent(parent, (
typename BinTree<T,S>::BinNode *) node);
892 *newLocation = parent;
894 this->
setNodeLocation(parent, (
typename BinTree<T,S>::BinNode **) newLocation);
898 if (!tmp->isNull()) {
900 this->
setNodeParent(tmp, (
typename BinTree<T,S>::BinNode *) parent);
902 newLocation = (RBNode **) parent->rightAddr();
904 newLocation = (RBNode **) parent->leftAddr();
917 if (!tmp->isNull()) {
918 if (!(*newLocation)->isNull()) result = this->
insert(tmp, *newLocation);
926 this->
setNodeLocation((
typename BinTree<T,S>::BinNode *) tmp, (
typename BinTree<T,S>::BinNode **) newLocation);
934 virtual const typename BinTree<T,S>::BinNode *
maxNode(
const typename BinTree<T,S>::BinNode * node)
const {
935 const RBNode * rnode = (
const RBNode *) node;
936 if (!rnode)
return NULL;
937 else if (rnode->isNull())
return rnode;
938 else if (!rnode->right()->isNull())
return this->
maxNode(rnode->right());
942 virtual const typename BinTree<T,S>::BinNode *
minNode(
const typename BinTree<T,S>::BinNode * node)
const {
943 const RBNode * rnode = (
const RBNode *) node;
944 if (!rnode)
return NULL;
945 else if (rnode->isNull())
return rnode;
946 else if (!rnode->left()->isNull())
return this->
minNode(rnode->left());
953 virtual void print(RBNode * rnode,
bool printNullNodes) {
954 if (rnode->right()) {
956 if (!isNull || (printNullNodes && isNull))
957 this->
print((RBNode *) rnode->right(), printNullNodes);
963 bool isNull = rnode->left()->isNull();
964 if (!isNull || (printNullNodes && isNull))
965 this->
print((RBNode *) rnode->left(), printNullNodes);
976 if (!rnode)
return 114;
978 if (!rnode->
left()->
isNull()) result = this->locateLeafNodes(outList, node->
left());
981 if (!rnode->
right()->
isNull()) result = this->locateLeafNodes(outList, node->
right());
985 result = outList->add(node);