相对于AVL树来说,红黑树去掉了AVL树里面的平衡因子,利用树节点的颜色来调整数的平衡。
红黑树的创建原则:
- 每个节点的颜色不是黑色就是红色
- 树的根节点是黑色的
- 如果一个节点的颜色是红色的,那么它的里两个孩子结点颜色是黑色的(即,没有两个连续的红色结点)
- 对于每个节点,在其后面的简单路径上面的黑色结点的个数是相同的
- 每个叶子节点都是黑色的(叶子节点是指空节点)
注:当满足上面的颜色限制的时候,最长路径上面的结点个数最多不超过最短路径的两倍
在红黑树里面需要挂入的结点的颜色无论红黑都可以的,但是假如是黑色,那么就不满足条件4,相对来说需要调整的范围大。假如是红色,那么不满足局部,对局部结点进行调整就可以了。所以在创建结点的时候结点的颜色标记成红色。
红黑树的插入
情况1:当树是空树的时候?
解决办法:将插入的结点直接挂上面,并且将结点的颜色标记成黑色。
情况2:插入的结点的父节点是黑色的?
解决方法:直接插入结点
情况3:当g–黑色,p–红色,u–红色?
解决方法:将p、u结点颜色改为黑色,g结点的颜色改为红色,然后再以g结点为基准向上调整
情况4:当g–黑,p–红,u不存在或者u–黑?
解决方法:将p、g结点的位置交换,并且两结点改变颜色。
情况5:当g–黑,p–红,u不存在或者u–黑,并且当p为g的左孩子,cur为p的右孩子或者p为g的右孩子,cur为p的左孩子?
解决方法:将cur结点进行左单旋或者右单旋,然后再按照情况4的解决方法进行调整。
红黑树的实现(仅创建):
#ifndef _RWTREE_H
#define _RWTREE_H
#include<iostream>
using namespace std;
enum color{RED,BLACK};
template<class T>
struct RBTreeNode
{
RBTreeNode(T d)
:left(NULL)
,right(NULL)
,_parent(NULL)
,_color(RED)
,value(d)
{}
RBTreeNode<T>* left;
RBTreeNode<T>* right;
RBTreeNode<T>* _parent;
color _color;
T value;
};
template<class T>
class RWTree
{
typedef RBTreeNode<T> Node;
public:
RWTree(T* arr,size_t size)
:_root(NULL)
{
if(NULL == arr)
return ;
for(int i=0;i<size;i++)
Insert(arr[i]);
}
void Insert(T d)
{
_Insert(_root,d);
}
private:
void _Insert(Node* root ,T d)
{
Node* cur = new Node(d);
if(NULL == root)
_root = cur;
else
{
while(root)
{
if(d < root->value)
root = root->left;
else
root = root->right;
}
if(d < root->value)
root->left = cur;
else
root->right = cur;
}
Adjust(cur);
}
void Adjust(Node* cur)
{
Node* parent = cur->_parent;
if(parent == NULL) //情况1
_root = cur;
else
{
if(parent->_color == RED )
{
Node* grand = parent->_parent;
Node* uncle = NULL;
if(grand->left == parent)
uncle = grand->right;
else if(grand->right == parent)
uncle = grand->left;
if(uncle && uncle->_color == RED) //情况3
{
grand->_color = RED;
parent->_color = BLACK;
uncle->_color = BLACK;
Adjust(grand);
}
else
{
if(cur == parent->left && parent == grand->left) //情况4
{
parent->_color = BLACK;
grand->_color = RED;
swap_R(grand);
}
else if( cur == parent->right && parent == grand->right )
{
parent->_color = BLACK;
grand->_color = RED;
swap_L(parent);
}
else if(cur == parent->right && parent == grand->left) //情况5
{
grand->left = cur;
cur->_parent = grand;
parent = cur->left;
parent->_parent = cur;
Adjust(parent);
}
else if(cur == parent->left && parent == grand->right)
{
grand->right = cur;
cur->_parent = grand;
parent = cur->right;
parent->_parent = cur;
Adjust(grand);
}
}
}
}
}
void swap_L(Node* parent)
{
Node* subR = parent->right;
Node* subRL = subR->left;
Node* pparent = parent->_parent;
if(subRL)
subRL->_parent = parent;
parent->right = subRL;
subR->left = parent;
if(pparent == NULL)
{
_root = subR;
}
else if(pparent->left == parent)
{
pparent->left = subR;
}
else
pparent->right = subR;
subR->_parent = pparent;
parent->_parent = subR;
}
void swap_R(Node* parent)
{
Node* pparent = parent->_parent;
Node* subL = parent->left;
Node* subLR = subL->right;
if(subLR)
subLR->_parent = parent;
parent->left = subLR;
subL->right = parent;
parent->_parent = subL;
if(NULL == pparent)
_root = subL;
else if(pparent->left == parent)
pparent->left = subL;
else
pparent->right = subL;
subL->_parent = pparent;
}
Node* _root;
};
#endif