6 # ifndef TPL_HTDRBTREE_H
7 # define TPL_HTDRBTREE_H
13 # include <tpl_binNodeUtils.H>
14 # include <tpl_arrayStack.H>
17 # define COLOR(p) (p->getColor())
19 using namespace BinNode_Utils;
26 typedef unsigned char Color;
36 friend class _Node :
public BinNode<Key>
43 static const _Node<Key> nodeSentinel;
49 getL() = _Node<Key>::Node::NullPtr;
50 getR() = _Node<Key>::Node::NullPtr;
57 static _Node<Key> *
const Node::NullPtr
58 =
const_cast<_Node<Key>*
>(&nodeSentinel);
61 :
BinNode<Key>(emptyCtor), color(c)
63 getL() = _Node<Key>::Node::NullPtr;
64 getR() = _Node<Key>::Node::NullPtr;
67 _Node(
const Key& _key)
68 :
BinNode<Key>(emptyCtor), color(RED)
71 getL() = _Node<Key>::Node::NullPtr;
72 getR() = _Node<Key>::Node::NullPtr;
75 Color& getColor() {
return color; }
77 Color getColor()
const {
return color; }
82 typedef MetaBinNode<_Node, Key> Node;
86 static Node *
const Node::NullPtr = Node::Node::NullPtr;
125 Node* getSibling(Node *p, Node *fp)
152 void restoreRedCondition(Node *p,
169 I(COLOR(ffp) == BLACK);
209 static void flipColors(Node* p)
211 I(p != Node::NullPtr);
212 I(COLOR(p) == BLACK);
213 I(COLOR(
LLINK(p)) == RED && COLOR(
RLINK(p)) == RED);
227 Node* searchFlipColorsAndInsert(Node *q)
229 I(q != Node::NullPtr);
230 I(root != Node::NullPtr);
232 I(
LLINK(q) == Node::NullPtr &&
RLINK(q) == Node::NullPtr);
245 if (COLOR(p) == BLACK && COLOR(
LLINK(p)) == RED
246 && COLOR(
RLINK(p)) == RED)
249 if (COLOR(fp) == RED)
251 I(fffp != Node::NullPtr);
252 restoreRedCondition(p, fp, ffp, fffp);
258 if (
LLINK(p) == Node::NullPtr)
264 if (
RLINK(p) == Node::NullPtr)
287 restoreRedCondition(q, p, fp, ffp);
301 Node* searchAndBuildPath(
const Key& key)
303 I(root != Node::NullPtr);
314 I(path.getLen() - 1.0 <= 2*log(n + 1)/log(2));
320 if (
LLINK(p) == Node::NullPtr)
322 I(path.getLen() - 1.0 <= 2*log(n + 1)/log(2));
330 if (
RLINK(p) == Node::NullPtr)
332 I(path.getLen() - 1.0 <= 2*log(n + 1)/log(2));
350 void findSuccAndSwap(Node *p, Node *&fp)
352 I(p != Node::NullPtr);
353 I(
RLINK(p) != Node::NullPtr);
354 I(fp != Node::NullPtr);
362 Node *&refToSearchPath = path.lookAt();
364 I(refToSearchPath == p);
368 Node *succ =
RLINK(p);
371 while (
LLINK(succ) != Node::NullPtr)
377 I(path.getLen() - 1.0 <= 2*log(n + 1)/log(2));
383 refToSearchPath = succ;
394 LLINK(p) = Node::NullPtr;
397 if (
RLINK(p) == succ)
407 Node *succr =
RLINK(succ);
415 Color tmp = COLOR(succ);
416 COLOR(succ) = COLOR(p);
444 void balanceDownAndColor(Node *p, Node *&fp, Node *&sp)
448 I(COLOR(fp) == BLACK);
450 I(COLOR(p) == BLACK);
455 Node *&ffp = path.lookAt();
459 ID(Node *oldSp = sp);
474 I(COLOR(ffp) == RED);
503 void rotateNephewAndColor(Node *fp, Node *sp, Node* np)
507 I(COLOR(sp) == BLACK);
511 Node *ffp = path.lookAt();
522 COLOR(sp) = COLOR(fp);
549 void doubleRotateNephewAndColor(Node *fp, Node *sp, Node *snp)
553 I(COLOR(sp) == BLACK);
554 I(COLOR(snp) == RED);
557 Node *ffp = path.lookAt();
563 if (
LLINK(sp) == snp)
575 COLOR(snp) = COLOR(fp);
586 static void colorSiblingAsRed(Node *sp)
588 I(COLOR(sp) == BLACK);
600 static void colorParentAndSibling(Node *fp, Node *sp)
604 I(COLOR(sp) == BLACK);
618 void removeAndFixBlackCondition(Node* q)
620 I(path.lookAt() == q);
624 Node* fq = path.lookAt(1);
628 I(fq != Node::NullPtr);
637 if (
LLINK(q) == Node::NullPtr)
646 if (
RLINK(q) == Node::NullPtr)
655 findSuccAndSwap(q, fq);
663 I(COLOR(p) == BLACK);
692 sp = getSibling(p, fp);
696 if (COLOR(sp) == RED)
697 balanceDownAndColor(p, fp, sp);
699 I(COLOR(sp) == BLACK);
713 if (COLOR(np) == RED)
715 rotateNephewAndColor(fp, sp, np);
719 if (COLOR(snp) == RED)
721 doubleRotateNephewAndColor(fp, sp, snp);
725 if (COLOR(fp) == RED)
727 colorParentAndSibling(fp, sp);
732 colorSiblingAsRed(sp);
745 ffHead(&headGrandParent),
746 root(headNode.getR())
749 RLINK(ffHead) = fHead;
750 COLOR(Node::NullPtr) = BLACK;
752 COLOR(fHead) = BLACK;
753 COLOR(ffHead) = BLACK;
775 I(p != Node::NullPtr);
777 I(
LLINK(p) == Node::NullPtr &&
RLINK(p) == Node::NullPtr);
779 if (root == Node::NullPtr)
788 return searchFlipColorsAndInsert(p);
802 return retVal == Node::NullPtr ? NULL : retVal;
814 Node*
remove(
const Key& key)
816 if (root == Node::NullPtr)
819 Node *p = searchAndBuildPath(key);
827 removeAndFixBlackCondition(p);
855 static void blackHeight(Node *p,
int &max,
int bh = 0)
857 if (COLOR(p) == BLACK)
862 if (
LLINK(p) == Node::NullPtr &&
RLINK(p) == Node::NullPtr)
870 if (
LLINK(p) != Node::NullPtr)
871 blackHeight(
LLINK(p), max, bh);
873 if (
RLINK(p) != Node::NullPtr)
874 blackHeight(
RLINK(p), max, bh);
881 static void testNode(Node* p)
884 COND_I(COLOR(p) == RED,
885 COLOR(
LLINK(p)) == BLACK && COLOR(
RLINK(p)) == BLACK);
890 blackHeight(p, max, bh);
Node * rotate_to_left(Node *p)
Definition: tpl_binNodeUtils.H:2422
#define LLINK(p)
Definition: tpl_binNode.H:196
Node * insert(Node *p)
Definition: tpl_hRbTree.H:773
HtdRbTree()
Constructor.
Definition: tpl_hRbTree.H:742
#define RLINK(p)
Definition: tpl_binNode.H:201
Definition: tpl_hRbTree.H:22
Node * rotate_to_right(Node *p)
Definition: tpl_binNodeUtils.H:2375
Node * search(const Key &key)
Definition: tpl_hRbTree.H:798
Node * searchInBinTree(Node *root, const typename Node::key_type &key, Compare &cmp)
Definition: tpl_binNodeUtils.H:1728
static const unsigned int MaxHeight
Estimated for 4 Gb of nodes of 1 byte (according to 2*lg(n+1) bound)
Definition: tpl_hRbTree.H:56
int preOrderRec(Node *root, void(*visitFct)(Node *, int, int))
Definition: tpl_binNodeUtils.H:93
void verifyRedBlack()
Definition: tpl_hRbTree.H:903
virtual ~HtdRbTree()
Destructor.
Definition: tpl_hRbTree.H:761
Node *& getRoot()
Gets HtdRbTree's root.
Definition: tpl_hRbTree.H:838
#define KEY(p)
Definition: tpl_binNode.H:206