In advance, this template class I found on the Internet (specifically where to find the forgotten)
The principle of red and black tree see: http://blog.csdn.net/v_JULY_v/article/details/6105630
Realize:
/** * Gs_rbtree.h:red-black Tree Implementation * * A simple C + + template wrapper of Linux kernel 2.6.1/rbtree.c * Wr Itten by Daly. 2009-11/* Red-black Tree Reference: * http://www.cnblogs.com/abatei/archive/2008/12/17/1356565.html *
Http://www.cs.princeton.edu/~rs/talks/LLRB/08Penn.pdf * * Usage: * rbtree<int, struct mytype> rbt;
* Rbt.insert (MYTYPE_OBJECT1);
* Rbt.insert (MYTYPE_OBJECT2); * Rbnode<int, struct mytype> *iter = Rbt.search (a)//search * if (ITER!= NULL) visit (iter->value);
Get value * Rbt.erase (12); *//alternative:rbt.erase_node (ITER);
(Faster but *iter would become null) * iter = Rbt.minimum (); * */#ifndef _gs_rbtree_h_ #define _GS_RBTREE_H_ #define RB_RED 1 #define RB_BLACK 0 template<typename _keytype
, TypeName _valtype> class Rbtree;
Red Black tree node Template<typename _keytype, TypeName _valtype> class Rbnode {public: _keytype key; _valtypeValue
Private:friend class Rbtree<_keytype, _valtype>;
Rbnode<_keytype, _valtype> *rb_parent;
Rbnode<_keytype, _valtype> *rb_left;
Rbnode<_keytype, _valtype> *rb_right;
int rb_color;
}; Red-black Tree Template<typename _keytype, TypeName _valtype> class Rbtree {typedef rbnode<_keytype, _valtype
> nodelink;
Public:rbtree (): M_root (NULL) {} ~rbtree ();
Search node by key.
Be careful to use the pointer it return.
nodelink* Search (_keytype key) {Nodelink *node = m_root;
while (node) {if (Key < Node->key) node = node->rb_left;
else if (key > Node->key) node = node->rb_right;
else//found match return node;
return NULL;
//insert and fix void Insert (_keytype key, _valtype value) {Nodelink *node = new Nodelink;
Fix New Leaf if (Insert_new_node (key, value, node)) {Insert_fix (node);
} void Erase_node (Nodelink *node);
void Erase (_keytype key); NodelInk* Minimun () {Nodelink *p = m_root;
while (P->rb_left!= NULL) p = p->rb_left;
return p;
} nodelink* Maximum () {Nodelink *p = m_root;
while (P->rb_right!= NULL) p = p->rb_right;
return p;
} protected:bool Insert_new_node (_keytype key, _valtype value, rbtree::nodelink* node);
void Insert_fix (Nodelink *node);
void Rotate_left (Nodelink *node);
void Rotate_right (Nodelink *node);
void Erase_fixup (Nodelink *node, Nodelink *parent); Protected:nodelink *m_root;
Tree root}; Template<typename _keytype, TypeName _valtype> Rbtree<_keytype, _valtype>::~rbtree () {while M_root NULL
) Erase_node (M_root); }/** * Initialize a new node. Just add to the tree ' s leaf * @return False if already exist. True if a new leaf * * Template<typename _keytype, TypeName _valtype> bool Rbtree<_keytype, _valtype>::insert_n Ew_node (_keytype key, _valtype value, rbtree::nodelink* node) {rbnode<_keytype, _valtype> **pp =&m_root;
Rbnode<_keytype, _valtype> *parent = NULL;
Rbnode<_keytype, _valtype> *pnode;
while (*pp) {pnode = parent = *pp;
if (Key < Pnode->key) {pp = &pnode->rb_left;
else if (Key > (*PP)->key) {pp = &pnode->rb_right;
else {//already exist pnode->value = value;
return false;
} node->rb_parent = parent;
Node->key = key;
Node->value = value;
Node->rb_color = rb_red;
Node->rb_left = Node->rb_right = NULL;
*PP = node; return true; A new node} template<typename _keytype, typename _valtype> void Rbtree<_keytype, _valtype>::rotate_left (R
Btree::nodelink *node) {rbnode<_keytype, _valtype> *right = node->rb_right; Update the right's left child and check whether it ' s null if ((Node->rb_right = right->rb_left)!= null) {Righ
t->rb_left->rb_parent = node; } right->rb_left = node; Become the right's left child//update ParenT and check whether it ' root if ((right->rb_parent = node->rb_parent)!= NULL) {if (node = = node->rb_parent-
>rb_left) Node->rb_parent->rb_left = right;
else node->rb_parent->rb_right = right; else {m_root = right;
Update the root} node->rb_parent = right; } template<typename _keytype, typename _valtype> void Rbtree<_keytype, _valtype>::rotate_right (RbTree::
Nodelink *node) {rbnode<_keytype, _valtype> *left = node->rb_left;
if ((Node->rb_left = left->rb_right)!= NULL) {left->rb_right->rb_parent = node;
} left->rb_right = node; if ((left->rb_parent = node->rb_parent)!= NULL) {if (node = = node->rb_parent->rb_right) node->rb_par
Ent->rb_right = left;
else Node->rb_parent->rb_left = left;
else {m_root = left;
} node->rb_parent = left; } template<typename _keytype, typename _valtype> void Rbtree<_keytype, _valtype>::insert_fix (RBtree::nodelink *node) {rbnode<_keytype, _valtype> *parent, *grandparent, *uncle and *tmp; Fix if two consecutive red node while (parent = node->rb_parent) && Parent->rb_color = = rb_red) {GRA Ndparent = parent->rb_parent; Grandparent sure to is not null//begin Left-branch case if (parent = grandparent->rb_left) {Uncle = Grandpa
rent->rb_right; Parent and uncle are both red if (uncle && uncle->rb_color = = rb_red) {uncle->rb_color = Rb_black;
Color Flip Parent->rb_color = Rb_black;
Grandparent->rb_color = rb_red;
node = grandparent; Continue Up to the root}//black Uncle if (parent->rb_right = node) {rotate_left (parent); left-leaning tmp = parent;
Update pointers after rotation parent = node;
node = tmp; } Parent->rb_color = Rb_black;
Color update before rotation grandparent->rb_color = rb_red; Rotate_rigHT (grandparent);
else {//begin Right branch case uncle = grandparent->rb_left;
if (Uncle && uncle->rb_color = = rb_red) {uncle->rb_color = Rb_black;
Parent->rb_color = Rb_black;
Grandparent->rb_color = rb_red;
node = grandparent;
Continue
} if (Parent->rb_left = node) {rotate_right (parent);
TMP = parent;
parent = node;
node = tmp;
} Parent->rb_color = Rb_black;
Grandparent->rb_color = rb_red;
Rotate_left (grandparent); } M_root->rb_color = Rb_black; Root should is black} template<typename _keytype, typename _valtype> void Rbtree<_keytype, _valtype>::eras
E (_keytype key) {rbnode<_keytype, _valtype> *node = search (key);
Erase_node (node); } template<typename _keytype, typename _valtype> void Rbtree<_keytype,_valtype>::erase_node (RbTree::
Nodelink *node) {rbnode<_keytype, _valtype> *child, *parent;
int color; if (node = NULL) retUrn
if (!node->rb_left)//right single link or leaf child = node->rb_right;
else if (!node->rb_right)//left single link child = node->rb_left;
Else//internal Node {nodelink *old = node, *left;
node = node->rb_right;
Find successor while (left = node->rb_left)!= NULL) {node = left; Child = node->rb_right;
Succesor ' s Child parent = node->rb_parent;
color = node->rb_color;
Update link if (child) child->rb_parent = parent;
if (parent) {if (Parent->rb_left = node) parent->rb_left = child;
else parent->rb_right = child;
else {//delete root m_root = child;
} if (node->rb_parent = = old) {parent = node;
//succussor Replace the node to is deleted node->rb_parent = old->rb_parent;
Node->rb_color = old->rb_color;
Node->rb_right = old->rb_right;
Node->rb_left = old->rb_left; if (old->rb_parent) {if (OLD->RB_parent->rb_left = = old) old->rb_parent->rb_left = node;
else Old->rb_parent->rb_right = node;
else {m_root = node;
} old->rb_left->rb_parent = node;
if (old->rb_right) {old->rb_right->rb_parent = node; } delete old; Release Memory Goto Fixup_color;
Jump to fix-up}//handle single link case or leaf parent = node->rb_parent;
color = node->rb_color;
if (child) child->rb_parent = parent;
if (parent) {if (Parent->rb_left = node) parent->rb_left = child;
else parent->rb_right = child;
else {m_root = child;
} delete node;
Fixup_color:if (color = = Rb_black) {Erase_fixup (child, parent); } template<typename _keytype, typename _valtype> void Rbtree<_keytype, _valtype>::erase_fixup (RbTree::
Nodelink *node, Rbtree::nodelink *parent) {rbnode<_keytype, _valtype> *other; Only to fix black child while (!node | | node->rb_color = = rb_black) && node!= m_root) {//handle left-branch case if (parent->rb_left = node) {other = Parent->rb_
Right
if (Other->rb_color = = rb_red) {//red brother. Just flip color other->rb_color = rb_black;
Parent->rb_color = rb_red;
Rotate_left (parent); other = parent->rb_right; Go down a level after rotation and go in fixing up}//black brother case and two black nephew if (!other->
Rb_left | |
Other->rb_left->rb_color = = rb_black) && (!other->rb_right | |
Other->rb_right->rb_color = = Rb_black)) {other->rb_color = rb_red; node = parent;
Go up parent = node->rb_parent;
else//less than two black nephew {//there's one black nephew if (!other->rb_right | |
Other->rb_right->rb_color = = rb_black) {rbnode<_keytype, _valtype> *o_left; if ((O_left = other->rb_left)!= NULL) {O_leFt->rb_color = Rb_black;
} Other->rb_color = rb_red;
Rotate_right (other);
other = parent->rb_right;
} Other->rb_color = parent->rb_color;
Parent->rb_color = Rb_black;
if (other->rb_right) Other->rb_right->rb_color = Rb_black;
Rotate_left (parent);
node = m_root; Break Finish} else//right case.
Symmetry code {other = parent->rb_left;
if (Other->rb_color = = rb_red) {other->rb_color = Rb_black;
Parent->rb_color = rb_red;
Rotate_right (parent);
other = parent->rb_left;
} if (!other->rb_left | |
Other->rb_left->rb_color = = rb_black) && (!other->rb_right | |
Other->rb_right->rb_color = = Rb_black)) {other->rb_color = rb_red;
node = parent;
Parent = node->rb_parent;
else {if (!other->rb_left | | Other->rb_left->rb_color = = rb_black) {Rbnode<_keyType, _valtype> *o_right;
if ((o_right = other->rb_right)!= NULL) {o_right->rb_color = Rb_black;
} Other->rb_color = rb_red;
Rotate_left (other);
other = parent->rb_left;
} Other->rb_color = parent->rb_color;
Parent->rb_color = Rb_black;
if (other->rb_left) {other->rb_left->rb_color = Rb_black;
} rotate_right (parent);
node = m_root;
Break
}}//end Loop if (node!= NULL) {node->rb_color = Rb_black;
}} #endif