红黑树的定义:红黑树是一棵二叉搜索树,它在每个结点上增加了一个存储位来表示结点的颜色,可以是red或者black,通过对任何一条从根节点到叶子结点上的简单路径来约束,红黑树保证最长路径不超过最短路径的两倍,因而近似平衡。
红黑树的性质:
1、每个结点不是红色就是黑色;
2、根节点是黑色的;
3、如果一个节点是红色的,则它的两个叶子结点是黑色的(没有两个连续的红色结点)
4、对于每个结点,从该结点到其所有后代叶子结点的简单路径上,均包含相同数目的黑色结点(每条路径上黑色结点的数量相等)
5、每个叶子结点都是黑色的(此处的叶子结点指的是空结点)
插入结点的简单分析:
情况一:cur为红,p为红,g为黑,u存在且为红
则p,u变黑,g变红,然后把g当成cur,继续向上调整。
情况二:cur为红,p为红,g为黑,u不存在/u为黑
p为g的左孩子,cur为p的左孩子,则进行右单旋转;相反,p为g的右孩子,cur为p的右孩子,则进行左单旋转 p、g变色–p变黑,g变红。
情况三:cur为红,p为红,g为黑,u不存在/u为黑
p为g的左孩子,cur为p的右孩子,则针对p做左单旋转;相反,p为g的右孩子,cur为p的左孩子,则针对p做右单旋转。此时转换成了情况2。
具体实现:
#include<iostream>
using namespace std;
enum Color{RED,BLACK};
template<typename K,typename V>
struct RBTreeNode
{
RBTreeNode(K key, V val, Color color = RED)
: _key(key)
, _val(val)
, _Left(NULL)
, _Right(NULL)
, _Parent(NULL)
, _color(color)
{}
K _key;
V _val;
RBTreeNode<K, V>* _Left;
RBTreeNode<K, V>* _Right;
RBTreeNode<K, V>* _Parent;
Color _color;
};
template<typename K,typename V>
class RBTree
{
typedef RBTreeNode<K, V> Node;
public:
RBTree()
: _pRoot(NULL)
{}
bool Insert(const K& key,const V& val)
{
if (NULL == _pRoot)
{
_pRoot = new Node(key, val, BLACK);
return true;
}
//找插入位置
Node* pCur = _pRoot;
Node* parent = NULL;
while (pCur)
{
if (key < pCur->_key)
{
parent = pCur;
pCur = pCur->_Left;
}
else if (key > pCur->_key)
{
parent = pCur;
pCur = pCur->_Right;
}
else
return false;
}
//插入结点
pCur = new Node(key, val);
if (key < parent->_key)
parent->_Left = pCur;
else
parent->_Right = pCur;
pCur->_Parent = parent;
//更改结点颜色
while (pCur != _pRoot && parent->_color == RED)
{
Node* grandFather = parent->_Parent;
if (parent == grandFather->_Left)
{
Node* uncle = grandFather->_Right;
if (uncle && uncle->_color == RED)//--情况1
{
parent->_color = BLACK;
uncle->_color = BLACK;
grandFather->_color = RED;
pCur = grandFather; //继续向上调整
parent = pCur->_Parent;
}
else//uncle不存在或uncle的color为BLACK -- 情况3
{
if (pCur == parent->_Right)//先左单旋
{
RotateLeft(parent);
swap(parent, pCur);//调整指针,即为情况2
}
parent->_color = BLACK;
grandFather->_color = RED;
RotateRight(grandFather);//再右单旋; 如果pCur == parent->_Left直接右单旋(情况2)
break;
}
}
else //parent == grandFather->_Right
{
Node* uncle = grandFather->_Left;
if (uncle && uncle->_color == RED)//情况1
{
parent->_color = BLACK;
uncle->_color = BLACK;
grandFather->_color = RED;
pCur = grandFather; //继续向上调整
parent = pCur->_Parent;
}
else//uncle不存在或uncle的color为BLACK -- 情况3
{
if (pCur == parent->_Left)//先右单旋
{
RotateRight(parent);
swap(parent, pCur);//调整指针,即为情况2
}
parent->_color = BLACK;
grandFather->_color = RED;
RotateLeft(grandFather);//再左单旋; 如果pCur == parent->_Right直接左单旋(情况2)
break;
}
}
}
_pRoot->_color = BLACK; //uncle的color为BLACK
return true;
}
void InOrder()
{
_InOrder(_pRoot);
cout << endl;
}
bool CheckRBTree()
{
if (NULL == _pRoot)
return true;
if (_pRoot->_color == RED)
return false;
size_t blackCount = 0, k = 0;
Node* pCur = _pRoot;
while (pCur)
{
if (pCur->_color == BLACK)
blackCount++;
pCur = pCur->_Left;
}
return _CheckRBTree(_pRoot, blackCount, k);
}
private:
void RotateLeft(Node* parent)
{
if (NULL == parent)
return;
Node* subR = parent->_Right;
Node* subRL = subR->_Left;
parent->_Right = subRL;
if (subRL)
subRL->_Parent = parent;
subR->_Left = parent;
subR->_Parent = parent->_Parent;
Node* ppParent = parent->_Parent;
parent->_Parent = subR;
if (ppParent)
{
if (parent == ppParent->_Left)
ppParent->_Left = subR;
else
ppParent->_Right = subR;
}
else
{
_pRoot = subR;
subR->_Parent = NULL;
}
parent = subR;
}
void RotateRight(Node* parent)
{
if (NULL == parent)
return;
Node* subL = parent->_Left;
Node* subLR = subL->_Right;
parent->_Left = subLR;
if (subLR)
subLR->_Parent = parent;
subL->_Right = parent;
subL->_Parent = parent->_Parent;
Node* ppParent = parent->_Parent;
parent->_Parent = subL;
if (ppParent)
{
if (parent == ppParent->_Left)
ppParent->_Left = subL;
else
ppParent->_Right = subL;
}
else
{
_pRoot = subL;
subL->_Parent = NULL;
}
parent = subL;
}
void _InOrder(Node* pRoot)
{
if (NULL == pRoot)
return;
_InOrder(pRoot->_Left);
cout << pRoot->_key << " ";
_InOrder(pRoot->_Right);
}
bool _CheckRBTree(Node* pRoot,const size_t blackCount,size_t k)
{
if (NULL == pRoot)
return true;
if (pRoot->_color == RED)
{
if (pRoot->_Parent->_color == RED)
{
cout << "不满足性质3!!" << endl;
return false;
}
}
else
k++;
if (pRoot && NULL == pRoot->_Left && NULL == pRoot->_Right)
{
if (blackCount == k)
return true;
else
{
cout << "不满足性质4!!" << endl;
return false;
}
}
else
{
return _CheckRBTree(pRoot->_Left, blackCount, k) && _CheckRBTree(pRoot->_Right, blackCount, k);
}
}
private:
Node* _pRoot;
};