红黑树是一棵二叉搜索树,它在每个结点上增加了一个存储位来表示结点的颜色,可以是red或者black,通过对任何一条从根节点到叶子结点上的简单路径来约束,红黑树保证最长路径不超过最短路径的两倍,因而近似平衡。
红黑树具有一下性质
1、每个节点不是红的就是黑的
2、根节点一定是黑的
3、没有连在一起的红色节点
4、从根节点到每个叶子的路径上的黑色节点数目相等
#pragma once
#include <iostream>
using namespace std;
enum COLOR
{
RED,
BLACK
};
template<class K,class V>
struct RBTreeNode
{
RBTreeNode(const K& key = K(), const V& value = V(), COLOR color = RED)
: _pRight(NULL)
, _pLeft(NULL)
, _pParent(NULL)
, _key(key)
, _value(value)
, _color(color)
{}
RBTreeNode<K, V>* _pRight;
RBTreeNode<K, V>* _pLeft;
RBTreeNode<K, V>* _pParent;
K _key;
V _value;
COLOR _color;
};
template<class K, class V, class Ref, class Ptr>
class RBIterator
{
typename typedef RBIterator<K, V, Ref, Ptr> self;
typename typedef RBTreeNode<K, V> Node;
public:
RBIterator()
{}
RBIterator(const self& it)
{
_pNode = it._pNode;
}
RBIterator(Node* ptmp)
{
_pNode = ptmp;
}
self& operator++()
{
Increment();
return *this;
}
self operator++(int)
{
self tmp = *this;
Increment();
return tmp;
}
self& operator--()
{
Decrement();
return *this;
}
self operator--(int)
{
self tmp = *this;
Decrement();
return tmp;
}
bool operator!=(const self& it)
{
return _pNode != it._pNode;
}
bool operator==(const self& it)
{
return _pNode == it._pNode;
}
Ref operator*()
{
return _pNode->_key;
}
Ptr operator->()
{
return &(_pNode->_key);
}
private:
void Increment()
{
if (_pNode->_pRight)
{
Node* ptmp = _pNode->_pRight;
while (ptmp->_pLeft)
ptmp = ptmp->_pLeft;
_pNode = ptmp;
}
else
{
Node* ptmp = _pNode->_pParent;
while (_pNode == ptmp->_pRight)
{
_pNode = ptmp;
ptmp = ptmp->_pParent;
}
if (_pNode->_pRight != ptmp)
_pNode = ptmp;
}
}
void Decrement()
{
if (_pNode->_color == RED && _pNode->_pParent->_pParent == _pNode)
_pNode = _pNode->_pLeft;;
else if (_pNode->_pLeft)
{
Node* ptmp = _pNode->_pLeft;
while (ptmp->_pRight)
ptmp = ptmp->_pRight;
_pNode = ptmp;
}
else
{
Node* ptmp = _pNode->_pParent;
while (_pNode == ptmp->_pLeft)
{
_pNode = ptmp;
ptmp = ptmp->_pParent;
}
_pNode = ptmp;
}
}
private:
Node* _pNode;
};
template<class K, class V>
class RBTree
{
typedef RBTreeNode<K, V> Node;
public:
typename typedef RBIterator<K, V, K&, K*> Itetator;
public:
RBTree()
:_pRoot(NULL)
{
_pHead = new Node;
_pHead->_pLeft = _pHead;
_pHead->_pRight = _pHead;
_pHead->_pParent = NULL;
}
bool Insert(const K& key, const V& value)
{
if (NULL == _pRoot)
{
_pRoot = new Node(key, value, BLACK);
_pRoot->_pParent = _pHead;
_pHead->_pParent = _pRoot;
_pHead->_pLeft = _pRoot;
_pHead->_pRight = _pRoot;
return true;
}
Node* pCur = _pRoot;
Node* pParent = NULL;
while (pCur)
{
if (key == pCur->_key)
return false;
else if (key > pCur->_key)
{
pParent = pCur;
pCur = pCur->_pRight;
}
else
{
pParent = pCur;
pCur = pCur->_pLeft;
}
}
pCur = new Node(key, value);
if (pParent->_key > key)
pParent->_pLeft = pCur;
else
pParent->_pRight = pCur;
pCur->_pParent = pParent;
while (pCur && RED == pCur->_color && pParent && RED == pParent->_color)
{
Node* pGar = pParent->_pParent;
if (pParent == pGar->_pLeft)
{
Node* pU = pGar->_pRight;
if (pU && RED == pU->_color)
{
pU->_color = BLACK;
pParent->_color = BLACK;
pGar->_color = RED;
pCur = pGar;
pParent = pGar->_pParent;
}
else
{
if (pCur == pParent->_pRight)
{
_RotateL(pParent);
std::swap(pParent, pCur);
}
_RotateR(pGar);
pParent->_color = BLACK;
pGar->_color = RED;
pCur = pParent->_pParent;
pParent = pCur->_pParent;
}
}
else
{
Node* pU = pGar->_pLeft;
if (pU && RED == pU->_color)
{
pU->_color = BLACK;
pParent->_color = BLACK;
pGar->_color = RED;
pCur = pGar;
pParent = pGar->_pParent;
}
else
{
if (pCur == pParent->_pLeft)
{
_RotateR(pParent);
std::swap(pParent, pCur);
}
_RotateL(pGar);
pParent->_color = BLACK;
pGar->_color = RED;
pCur = pParent->_pParent;
pParent = pCur->_pParent;
}
}
}
_pRoot->_color = BLACK;
_pHead->_pRight = _GetmaxNode();
_pHead->_pLeft = _GetminNode();
return true;
}
size_t Size()
{
size_t count = 0;
_Size(_pRoot,count);
return count;
}
Node* Begin()
{
return _pHead->_pLeft;
}
Node* End()
{
return _pHead;
}
bool CheckRBTree()
{
size_t count = 0;
_blackCount(_pRoot, count);
return _CheckRBTree(_pRoot, count, 0);
}
void InOrder()
{
cout << "InOrder: ";
_InOrder(_pRoot);
cout << endl;
}
private:
Node* _GetminNode()
{
if (NULL == _pRoot)
return _pRoot;
Node* pRoot = _pRoot;
while (pRoot->_pLeft)
pRoot = pRoot->_pLeft;
return pRoot;
}
Node* _GetmaxNode()
{
if (NULL == _pRoot)
return _pRoot;
Node* pRoot = _pRoot;
while (pRoot->_pRight)
pRoot = pRoot->_pRight;
return pRoot;
}
void _blackCount(Node* pRoot, size_t &count)
{
while (pRoot)
{
if (pRoot->_color == BLACK)
count++;
pRoot = pRoot->_pLeft;
}
}
void _RotateR(Node* pParent)
{
Node* pSubL = pParent->_pLeft;
Node* pSubLR = pSubL->_pRight;
pParent->_pLeft = pSubLR;
if (pSubLR)
pSubLR->_pParent = pParent;
pSubL->_pRight = pParent;
Node* pPParent = pParent->_pParent;
pParent->_pParent = pSubL;
pSubL->_pParent = pPParent;
if (_pHead == pPParent)
{
_pRoot = pSubL;
_pHead->_pParent = _pRoot;
_pRoot->_pParent = _pHead;
}
else
{
if (pPParent->_pLeft == pParent)
pPParent->_pLeft = pSubL;
else
pPParent->_pRight = pSubL;
}
}
void _RotateL(Node* pParent)
{
Node* pSubR = pParent->_pRight;
Node* pSubRL = pSubR->_pLeft;
pParent->_pRight = pSubRL;
if (pSubRL)
pSubRL->_pParent = pParent;
pSubR->_pLeft = pParent;
Node* pPParent = pParent->_pParent;
pParent->_pParent = pSubR;
pSubR->_pParent = pPParent;
if (_pHead != pPParent)
{
if (pPParent->_pLeft == pParent)
pPParent->_pLeft = pSubR;
else
pPParent->_pRight = pSubR;
}
else
{
_pRoot = pSubR;
_pHead->_pParent = _pRoot;
_pRoot->_pParent = _pHead;
}
}
void _InOrder(Node* pRoot)
{
if (pRoot)
{
_InOrder(pRoot->_pLeft);
cout << pRoot->_key << ' ';
_InOrder(pRoot->_pRight);
}
}
bool _CheckRBTree(Node* pRoot, const size_t blackCount, size_t k)
{
if (pRoot == NULL)
return true;
if (pRoot->_color == BLACK)
k++;
if (pRoot->_color == RED && pRoot->_pParent->_color == RED)
return false;
if (pRoot->_pLeft == NULL && pRoot->_pRight == NULL)
{
if (blackCount == k)
return true;
}
return _CheckRBTree(pRoot->_pLeft, blackCount, k) && _CheckRBTree(pRoot->_pRight, blackCount, k);
}
void _Size(Node* pRoot,size_t& count)
{
if (pRoot)
{
count++;
_Size(pRoot->_pLeft, count);
_Size(pRoot->_pRight, count);
}
}
private:
Node* _pRoot;
Node* _pHead;
};