红黑树的性质:
(1)每个结点只能是红色或者黑色
(2) 根结点是黑色的
(3) 叶子结点是黑色的
(4) 如果一个结点是红色的,那么它的两个孩子都是黑色的
(5) 对于每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点
vim rbtree.h
#ifndef RBTREE_MODULE_H_
#define RBTREE_MODELE_H_
#include <iostream>
#include <stack>
#include <queue>
using std::cout;
using std::endl;
using std::stack;
using std::queue;
namespace rbtree
{
enum Color
{
Red = 0,
Black
};
template<typename T>
struct Node
{
Color color;
T key;
Node<T> *parent;
Node<T> *left;
Node<T> *right;
Node(T k, Color c) : color(c), key(k), parent(NULL), left(NULL), right(NULL)
{ }
};
template<typename T>
struct StackNode
{
Node<T> *data;
bool tag;
};
template<typename T>
class Rbtree
{
public:
Rbtree() { root = NULL; }
~Rbtree() { Rbtree_ClearNode(root); }
void Left_Rotate(Node<T> *cur);
void Right_Rotate(Node<T> *cur);
void Rbtree_Insert(const T val);
void Rbtree_Insert_Fixup(Node<T> *t);
Node<T> * Rbtree_Search(const T val);
Node<T> * Rbtree_Min(Node<T> *cur);
Node<T> * Rbtree_Successor(Node<T> *cur);
void Rbtree_Delete(const T val);
void Rbtree_Delete_Fixup(Node<T> *t);
void Rbtree_InOrder();
void Rbtree_PreOrder();
void Rbtree_PostOrder();
void Rbtree_LayerOrder();
void Rbtree_Visit(Node<T> *t);
void Rbtree_ClearNode(Node<T> *t);
int Rbtree_Height();
private:
Node<T> *root;
};
void Rbtree<T>::Left_Rotate(Node<T> *cur)
{
if (NULL == cur)
return ;
Node<T> *tmp = cur->right;
tmp->parent = cur->parent;
cur->right = tmp->left;
if (NULL != tmp->left)
tmp->left->parent = cur;
if (NULL == cur->parent)
root = tmp;
else if (cur->parent->left == cur)
cur->parent->left = tmp;
else
cur->parent->right = tmp;
tmp->left = cur;
cur->parent = tmp;
}
template<typename T>
void Rbtree<T>::Right_Rotate(Node<T> *cur)
{
if (NULL == cur)
return ;
Node<T> *tmp = cur->left;
tmp->parent = cur->parent;
cur->left = tmp->right;
if (NULL != tmp->right)
tmp->right->parent = cur;
if (NULL == cur->parent)
root = tmp;
else if (cur->parent->left == cur)
cur->parent->left = tmp;
else
cur->parent->right = tmp;
tmp->right = cur;
cur->parent = tmp;
}
template<typename T>
void Rbtree<T>::Rbtree_Insert(const T val)
{
Node<T> *fresh = new Node<T>(val, Red);
if (NULL == fresh)
{
cout << "Fail to allocate memory for " << val << endl;
return ;
}
Node<T> *tmp = root;
Node<T> *dst = NULL;
while (NULL != tmp)
{
dst = tmp;
if (val < tmp->key)
tmp = tmp->left;
else
tmp = tmp->right;
}
if (NULL == dst) // empty tree before
root = fresh;
else
{
fresh->parent = dst;
if (val < dst->key)
dst->left = fresh;
else
dst->right = fresh;
}
Rbtree_Insert_Fixup(fresh);
}
void Rbtree<T>::Rbtree_Insert_Fixup(Node<T> *t)
{
Node<T> *uncle = NULL;
while (NULL != t->parent && Red == t->parent->color && NULL != t->parent->parent)
{
// left tree
if (t->parent == t->parent->parent->left)
{
uncle = t->parent->parent->right;
// uncle is red
if (NULL != uncle && Red == uncle->color)
{
// handle the violation of property 4
t->parent->color = Black;
uncle->color = Black;
// keep property 5
t->parent->parent->color = Red;
// move up 2 layer
t = t->parent->parent;
}
else
{
// t is a right son
if (t == t->parent->right)
{
t = t->parent;
Left_Rotate(t);
}
// t is a left son
t->parent->color = Black;
t->parent->parent->color = Red;
Right_Rotate(t->parent->parent);
}
}
else //right tree
{
uncle = t->parent->parent->left;
if (NULL != uncle && Red == uncle->color)
{
t->parent->color = Black;
uncle->color = Black;
t->parent->parent->color = Red;
t = t->parent->parent;
}
else
{
if (t == t->parent->left)
{
t = t->parent;
Right_Rotate(t);
}
t->parent->color = Black;
t->parent->parent->color = Red;
Left_Rotate(t->parent->parent);
}
}
}
root->color = Black;
}
template<typename T>
Node<T> * Rbtree<T>::Rbtree_Search(const T val)
{
Node<T> * tmp = root;
while (NULL != tmp && val != tmp->key)
{
if (val < tmp->key)
tmp = tmp->left;
else
tmp = tmp->right;
}
return tmp;
}
template<typename T>
Node<T> * Rbtree<T>::Rbtree_Min(Node<T> *cur)
{
if (NULL == cur)
return NULL;
while (NULL != cur->left)
cur = cur->left;
return cur;
}
template<typename T>
Node<T> * Rbtree<T>::Rbtree_Successor(Node<T> *cur)
{
if (NULL != cur->right)
return Rbtree_Min(cur->right);
Node<T> *tmp = cur->parent;
while (NULL != tmp && cur == tmp->right)
{
cur = tmp;
tmp = tmp->parent;
}
return tmp;
}
template<typename T>
void Rbtree<T>::Rbtree_Delete(const T val)
{
Node<T> *dst = Rbtree_Search(val);
if (NULL == dst)
{
cout << "Can not find " << val << endl;
return ;
}
cout << "delete " << val << endl;
Node<T> *discard = NULL;
Node<T> *dson = NULL;
if (NULL == dst->left || NULL == dst->right)
discard = dst;
else
discard = Rbtree_Successor(dst);
if (NULL != discard->left)
dson = discard->left;
else
dson = discard->right;
if (NULL != dson)
dson->parent = discard->parent;
if (NULL == discard->parent)
root = dson;
else if (discard == discard->parent->left)
discard->parent->left = dson;
else
discard->parent->right = dson;
if (dst != discard)
dst->key = discard->key;
if (Black == discard->color && NULL != dson)
Rbtree_Delete_Fixup(dson);
delete discard;
discard = NULL;
}
void Rbtree<T>::Rbtree_Delete_Fixup(Node<T> *t)
{
Node<T> *sibling = NULL;
while (t != root && Black == t->color && NULL != t->parent)
{
if (t == t->parent->left)
{
sibling = t->parent->right;
if (Red == sibling->color)
{
sibling->color = Black;
t->parent->color = Red;
Left_Rotate(t->parent);
sibling = t->parent->right;
}
else if (Black == sibling->left->color && Black == sibling->right->color)
{
sibling->color = Red;
t = t->parent;
}
else
{
if (Black == sibling->right->color) //left:red;right:black
{
sibling->left->color = Black;
sibling->color = Red;
Right_Rotate(sibling);
sibling = t->parent->right;
}
sibling->color = t->parent->color;
t->parent->color = Black;
sibling->right->color = Black;
Left_Rotate(t->parent);
t = root;
}
}
else
{
sibling = t->parent->left;
if (Red == sibling->color) //sibling:red
{
sibling->color = Black;
t->parent->color = Red;
Right_Rotate(t->parent);
sibling = t->parent->left;
}
else if (Black == sibling->left->color && Black == sibling->right->color)
{
sibling->color = Red;
t = t->parent;
}
else
{
if (Black == sibling->left->color) //left:red;right:black
{
sibling->right->color = Black;
sibling->color = Red;
Left_Rotate(sibling);
sibling = t->parent->left;
}
sibling->color = t->parent->color;
t->parent->color = Black;
sibling->left->color = Black;
Right_Rotate(t->parent);
t = root;
}
}
}
t->color = Black;
}
template<typename T>
void Rbtree<T>::Rbtree_InOrder()
{
Node<T> *tmp = root;
stack<Node<T> *> st;
while (NULL != tmp || !st.empty())
{
while (NULL != tmp)
{
st.push(tmp);
tmp = tmp->left;
}
tmp = st.top();
Rbtree_Visit(tmp);
st.pop();
tmp = tmp->right;
}
}
template<typename T>
void Rbtree<T>::Rbtree_PreOrder()
{
Node<T> *tmp = root;
stack<Node<T> *> st;
while (NULL != tmp || !st.empty())
{
while (NULL != tmp)
{
Rbtree_Visit(tmp);
st.push(tmp);
tmp = tmp->left;
}
tmp = st.top();
st.pop();
tmp = tmp->right;
}
}
template<typename T>
void Rbtree<T>::Rbtree_PostOrder()
{
StackNode<T> node;
stack<StackNode<T> > st;
Node<T> *tmp = root;
do{
while (NULL != tmp)
{
node.data = tmp;
node.tag = false;
st.push(node);
tmp = tmp->left;
}
while (!st.empty() && st.top().tag)
{
tmp = st.top().data;
st.pop();
Rbtree_Visit(tmp);
}
if (!st.empty())
{
st.top().tag = true;
tmp = st.top().data->right;
}
} while(!st.empty());
}
template<typename T>
void Rbtree<T>::Rbtree_LayerOrder()
{
Node<T> *tmp = root;
if (NULL == tmp)
return ;
queue<Node<T> *> qu;
qu.push(tmp);
while (!qu.empty())
{
//Rbtree_Visit(tmp);
tmp = qu.front();
qu.pop();
if (tmp->left)
qu.push(tmp->left);
if (tmp->right)
qu.push(tmp->right);
Rbtree_Visit(tmp);
}
}
template<typename T>
void Rbtree<T>::Rbtree_Visit(Node<T> *t)
{
if (NULL != t)
cout << t->key << " , " << t->color << endl;
}
template<typename T>
void Rbtree<T>::Rbtree_ClearNode(Node<T> *t)
{
if (NULL != t)
{
Rbtree_ClearNode(t->left);
Rbtree_ClearNode(t->right);
cout << "clear node = " << t->key << endl;
delete t;
t = NULL;
}
}
template<typename T>
int Rbtree<T>::Rbtree_Height()
{
Node<T> *tmp = root;
if (NULL == tmp)
return 0;
int height = 0;
queue<Node<T> *> qu;
qu.push(tmp);
qu.push(NULL);
++height;
while (!qu.empty())
{
tmp = qu.front();
qu.pop();
if (tmp)
{
if (NULL != tmp->left)
qu.push(tmp->left);
if (NULL != tmp->right)
qu.push(tmp->right);
}
else if (!qu.empty())
{
++height;
qu.push(NULL);
}
}
return height;
}
}
#endif
main.cpp
#include "rbtree.h"
using namespace::rbtree;
{
Rbtree<int> rbt;
int arr[11] = {4, 2, 1, 3, 8, 7, 5, 6, 10, 9, 11};
for (int i = 0; i < 11; ++i)
rbt.Rbtree_Insert(arr[i]);
rbt.Rbtree_InOrder();
rbt.Rbtree_Delete(3);
rbt.Rbtree_InOrder();
cout << "PostOrder" << endl;
rbt.Rbtree_PostOrder();
cout << "LayerOrder" << endl;
rbt.Rbtree_LayerOrder();
cout << "Height = " << rbt.Rbtree_Height() << endl;
return 0;
}
(1)每个结点只能是红色或者黑色
(2) 根结点是黑色的
(3) 叶子结点是黑色的
(4) 如果一个结点是红色的,那么它的两个孩子都是黑色的
(5) 对于每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点
vim rbtree.h
#ifndef RBTREE_MODULE_H_
#define RBTREE_MODELE_H_
#include <iostream>
#include <stack>
#include <queue>
using std::cout;
using std::endl;
using std::stack;
using std::queue;
namespace rbtree
{
enum Color
{
Red = 0,
Black
};
template<typename T>
struct Node
{
Color color;
T key;
Node<T> *parent;
Node<T> *left;
Node<T> *right;
Node(T k, Color c) : color(c), key(k), parent(NULL), left(NULL), right(NULL)
{ }
};
template<typename T>
struct StackNode
{
Node<T> *data;
bool tag;
};
template<typename T>
class Rbtree
{
public:
Rbtree() { root = NULL; }
~Rbtree() { Rbtree_ClearNode(root); }
void Left_Rotate(Node<T> *cur);
void Right_Rotate(Node<T> *cur);
void Rbtree_Insert(const T val);
void Rbtree_Insert_Fixup(Node<T> *t);
Node<T> * Rbtree_Search(const T val);
Node<T> * Rbtree_Min(Node<T> *cur);
Node<T> * Rbtree_Successor(Node<T> *cur);
void Rbtree_Delete(const T val);
void Rbtree_Delete_Fixup(Node<T> *t);
void Rbtree_InOrder();
void Rbtree_PreOrder();
void Rbtree_PostOrder();
void Rbtree_LayerOrder();
void Rbtree_Visit(Node<T> *t);
void Rbtree_ClearNode(Node<T> *t);
int Rbtree_Height();
private:
Node<T> *root;
};
void Rbtree<T>::Left_Rotate(Node<T> *cur)
{
if (NULL == cur)
return ;
Node<T> *tmp = cur->right;
tmp->parent = cur->parent;
cur->right = tmp->left;
if (NULL != tmp->left)
tmp->left->parent = cur;
if (NULL == cur->parent)
root = tmp;
else if (cur->parent->left == cur)
cur->parent->left = tmp;
else
cur->parent->right = tmp;
tmp->left = cur;
cur->parent = tmp;
}
template<typename T>
void Rbtree<T>::Right_Rotate(Node<T> *cur)
{
if (NULL == cur)
return ;
Node<T> *tmp = cur->left;
tmp->parent = cur->parent;
cur->left = tmp->right;
if (NULL != tmp->right)
tmp->right->parent = cur;
if (NULL == cur->parent)
root = tmp;
else if (cur->parent->left == cur)
cur->parent->left = tmp;
else
cur->parent->right = tmp;
tmp->right = cur;
cur->parent = tmp;
}
template<typename T>
void Rbtree<T>::Rbtree_Insert(const T val)
{
Node<T> *fresh = new Node<T>(val, Red);
if (NULL == fresh)
{
cout << "Fail to allocate memory for " << val << endl;
return ;
}
Node<T> *tmp = root;
Node<T> *dst = NULL;
while (NULL != tmp)
{
dst = tmp;
if (val < tmp->key)
tmp = tmp->left;
else
tmp = tmp->right;
}
if (NULL == dst) // empty tree before
root = fresh;
else
{
fresh->parent = dst;
if (val < dst->key)
dst->left = fresh;
else
dst->right = fresh;
}
Rbtree_Insert_Fixup(fresh);
}
void Rbtree<T>::Rbtree_Insert_Fixup(Node<T> *t)
{
Node<T> *uncle = NULL;
while (NULL != t->parent && Red == t->parent->color && NULL != t->parent->parent)
{
// left tree
if (t->parent == t->parent->parent->left)
{
uncle = t->parent->parent->right;
// uncle is red
if (NULL != uncle && Red == uncle->color)
{
// handle the violation of property 4
t->parent->color = Black;
uncle->color = Black;
// keep property 5
t->parent->parent->color = Red;
// move up 2 layer
t = t->parent->parent;
}
else
{
// t is a right son
if (t == t->parent->right)
{
t = t->parent;
Left_Rotate(t);
}
// t is a left son
t->parent->color = Black;
t->parent->parent->color = Red;
Right_Rotate(t->parent->parent);
}
}
else //right tree
{
uncle = t->parent->parent->left;
if (NULL != uncle && Red == uncle->color)
{
t->parent->color = Black;
uncle->color = Black;
t->parent->parent->color = Red;
t = t->parent->parent;
}
else
{
if (t == t->parent->left)
{
t = t->parent;
Right_Rotate(t);
}
t->parent->color = Black;
t->parent->parent->color = Red;
Left_Rotate(t->parent->parent);
}
}
}
root->color = Black;
}
template<typename T>
Node<T> * Rbtree<T>::Rbtree_Search(const T val)
{
Node<T> * tmp = root;
while (NULL != tmp && val != tmp->key)
{
if (val < tmp->key)
tmp = tmp->left;
else
tmp = tmp->right;
}
return tmp;
}
template<typename T>
Node<T> * Rbtree<T>::Rbtree_Min(Node<T> *cur)
{
if (NULL == cur)
return NULL;
while (NULL != cur->left)
cur = cur->left;
return cur;
}
template<typename T>
Node<T> * Rbtree<T>::Rbtree_Successor(Node<T> *cur)
{
if (NULL != cur->right)
return Rbtree_Min(cur->right);
Node<T> *tmp = cur->parent;
while (NULL != tmp && cur == tmp->right)
{
cur = tmp;
tmp = tmp->parent;
}
return tmp;
}
template<typename T>
void Rbtree<T>::Rbtree_Delete(const T val)
{
Node<T> *dst = Rbtree_Search(val);
if (NULL == dst)
{
cout << "Can not find " << val << endl;
return ;
}
cout << "delete " << val << endl;
Node<T> *discard = NULL;
Node<T> *dson = NULL;
if (NULL == dst->left || NULL == dst->right)
discard = dst;
else
discard = Rbtree_Successor(dst);
if (NULL != discard->left)
dson = discard->left;
else
dson = discard->right;
if (NULL != dson)
dson->parent = discard->parent;
if (NULL == discard->parent)
root = dson;
else if (discard == discard->parent->left)
discard->parent->left = dson;
else
discard->parent->right = dson;
if (dst != discard)
dst->key = discard->key;
if (Black == discard->color && NULL != dson)
Rbtree_Delete_Fixup(dson);
delete discard;
discard = NULL;
}
void Rbtree<T>::Rbtree_Delete_Fixup(Node<T> *t)
{
Node<T> *sibling = NULL;
while (t != root && Black == t->color && NULL != t->parent)
{
if (t == t->parent->left)
{
sibling = t->parent->right;
if (Red == sibling->color)
{
sibling->color = Black;
t->parent->color = Red;
Left_Rotate(t->parent);
sibling = t->parent->right;
}
else if (Black == sibling->left->color && Black == sibling->right->color)
{
sibling->color = Red;
t = t->parent;
}
else
{
if (Black == sibling->right->color) //left:red;right:black
{
sibling->left->color = Black;
sibling->color = Red;
Right_Rotate(sibling);
sibling = t->parent->right;
}
sibling->color = t->parent->color;
t->parent->color = Black;
sibling->right->color = Black;
Left_Rotate(t->parent);
t = root;
}
}
else
{
sibling = t->parent->left;
if (Red == sibling->color) //sibling:red
{
sibling->color = Black;
t->parent->color = Red;
Right_Rotate(t->parent);
sibling = t->parent->left;
}
else if (Black == sibling->left->color && Black == sibling->right->color)
{
sibling->color = Red;
t = t->parent;
}
else
{
if (Black == sibling->left->color) //left:red;right:black
{
sibling->right->color = Black;
sibling->color = Red;
Left_Rotate(sibling);
sibling = t->parent->left;
}
sibling->color = t->parent->color;
t->parent->color = Black;
sibling->left->color = Black;
Right_Rotate(t->parent);
t = root;
}
}
}
t->color = Black;
}
template<typename T>
void Rbtree<T>::Rbtree_InOrder()
{
Node<T> *tmp = root;
stack<Node<T> *> st;
while (NULL != tmp || !st.empty())
{
while (NULL != tmp)
{
st.push(tmp);
tmp = tmp->left;
}
tmp = st.top();
Rbtree_Visit(tmp);
st.pop();
tmp = tmp->right;
}
}
template<typename T>
void Rbtree<T>::Rbtree_PreOrder()
{
Node<T> *tmp = root;
stack<Node<T> *> st;
while (NULL != tmp || !st.empty())
{
while (NULL != tmp)
{
Rbtree_Visit(tmp);
st.push(tmp);
tmp = tmp->left;
}
tmp = st.top();
st.pop();
tmp = tmp->right;
}
}
template<typename T>
void Rbtree<T>::Rbtree_PostOrder()
{
StackNode<T> node;
stack<StackNode<T> > st;
Node<T> *tmp = root;
do{
while (NULL != tmp)
{
node.data = tmp;
node.tag = false;
st.push(node);
tmp = tmp->left;
}
while (!st.empty() && st.top().tag)
{
tmp = st.top().data;
st.pop();
Rbtree_Visit(tmp);
}
if (!st.empty())
{
st.top().tag = true;
tmp = st.top().data->right;
}
} while(!st.empty());
}
template<typename T>
void Rbtree<T>::Rbtree_LayerOrder()
{
Node<T> *tmp = root;
if (NULL == tmp)
return ;
queue<Node<T> *> qu;
qu.push(tmp);
while (!qu.empty())
{
//Rbtree_Visit(tmp);
tmp = qu.front();
qu.pop();
if (tmp->left)
qu.push(tmp->left);
if (tmp->right)
qu.push(tmp->right);
Rbtree_Visit(tmp);
}
}
template<typename T>
void Rbtree<T>::Rbtree_Visit(Node<T> *t)
{
if (NULL != t)
cout << t->key << " , " << t->color << endl;
}
template<typename T>
void Rbtree<T>::Rbtree_ClearNode(Node<T> *t)
{
if (NULL != t)
{
Rbtree_ClearNode(t->left);
Rbtree_ClearNode(t->right);
cout << "clear node = " << t->key << endl;
delete t;
t = NULL;
}
}
template<typename T>
int Rbtree<T>::Rbtree_Height()
{
Node<T> *tmp = root;
if (NULL == tmp)
return 0;
int height = 0;
queue<Node<T> *> qu;
qu.push(tmp);
qu.push(NULL);
++height;
while (!qu.empty())
{
tmp = qu.front();
qu.pop();
if (tmp)
{
if (NULL != tmp->left)
qu.push(tmp->left);
if (NULL != tmp->right)
qu.push(tmp->right);
}
else if (!qu.empty())
{
++height;
qu.push(NULL);
}
}
return height;
}
}
#endif
main.cpp
#include "rbtree.h"
using namespace::rbtree;
{
Rbtree<int> rbt;
int arr[11] = {4, 2, 1, 3, 8, 7, 5, 6, 10, 9, 11};
for (int i = 0; i < 11; ++i)
rbt.Rbtree_Insert(arr[i]);
rbt.Rbtree_InOrder();
rbt.Rbtree_Delete(3);
rbt.Rbtree_InOrder();
cout << "PostOrder" << endl;
rbt.Rbtree_PostOrder();
cout << "LayerOrder" << endl;
rbt.Rbtree_LayerOrder();
cout << "Height = " << rbt.Rbtree_Height() << endl;
return 0;
}