在说红黑树之前,我们先来认识一下它:
首先强调一点:红黑树也是二叉搜索树。那么它就满足二叉搜索树的性质,除此之外,他还有几个比较特殊的性质,了解这些,有助于我们后面的分析
性质:
1、红黑树所有的节点都有颜色(红或黑)
2、红黑树的根结点是黑色的
3、红黑树的两个红色节点不能相连
4、红黑树的每一条链的黑节点的个数相同
5、所有空的节点都是黑色的
知道了这些之后开始进入红黑树的创建:
显然这就是红黑树的插入操作的编写了,那么要想将一个节点插入红黑树中,首先你得判断红黑树是不是空的,如果是空的,那么直接就可以插入;不是空的,那么得找插入位置,然后再插入,这一点和二叉搜索树的插入是一样的。不过需要注意,最后把根结点置成黑色的
但是之后呢?
插入的节点我们都默认为红色的,但是性质3说,红色的节点不能相链,如果,之后我们不管的话,性质3肯定不会满足的,所以我们需要对红黑树进行调解,让其满足这些性质。那么我们就需要分情况讨论了,我们重点分析一下,两个红色节点相链的情况怎么处理。
总共可以分为3种情况:
情况一:
双亲结点为红色,祖先结点为黑色, 叔叔节点存在,且为红色
其实这个图里包含了四种情况,我只是将其中的一种情况中的转化后的形式画了出来,其他的也一样。
情况二:
双亲结点为红色,祖先结点为黑色,叔叔节点不存在或存在为黑色
这种情况是:双亲在祖先节点的左的同时pCur在双亲的左;或是双亲在祖先节点的右的同时,pCur在双亲的右。
这样我们就可以进行单旋处理,根据情况调用左单旋还是右单旋。
情况三:
双亲结点为红色,祖先结点为黑色,叔叔节点不存在或存在为黑色
这个和情况二是互补的,情况二中剩下的都是不能单旋直接处理的,那么就需要双旋,图中画的是左右双旋,先左旋之后,我们发现,和情况二的一样,那么代码中这一块就可以放在一起处理。
不过,这里需要注意一点,就是,左旋之后只想pCur变成了双亲,而parent变成了孩子,所以,在第一次旋转之后先对这两个指针进行交换,在进行第二次旋转。
最后将插入写完之后,我们可以写一个函数来测试一下这个是不是红黑树,这个其实也是对红黑树的性质的检验。其中重点验证性质3和性质4。那么我们来分析一下这步骤:
1、判断这个树是不是空树,是的话,直接返回true
2、验证性质2,判断根结点的颜色是不是黑色的,是,返回true
3、要验证性质三,得遍历整个树,而性质4的验证也要这莫做,那么我们将这两个一起验证。那么首先我们得求出一条链的黑色节点的个数,并将其保存起来,再递归遍历左右子树,验证。
//无迭代器
template<class K, class V>
class RBTree
{
typedef RBTreeNode<K, V> Node;
public:
RBTree()
:_pRoot(NULL)
{}
// 首先:搜索树
bool Insert(const K& key, const V& value)
{
if (_pRoot == NULL)
{
_pRoot = new Node(key, value);
_pRoot->_color = BLACK;
return true;
}
//找插入位置
Node*pCur = _pRoot;
Node*parent = NULL;
while (pCur)
{
if (key < pCur->_key)
{
parent = pCur;
pCur = pCur->_pLeft;
}
else if (key>pCur->_key)
{
parent = pCur;
pCur = pCur->_pRight;
}
else
return false;
}
//插入
pCur = new Node(key, value);
if (key < parent->_key)
parent->_pLeft = pCur;
else
parent->_pRight = pCur;
pCur->_pParent = parent;//注意,不要遗漏了。。。
//看红黑树是否还满足其性质(分情况讨论)
while (_pRoot!=pCur && pCur->_pParent->_color == RED)
{
Node* gf = parent->_pParent;//保存双亲的双亲
//gf肯定存在,因为,如果不存在,那么parent就是根结点,是黑色的,不会进入这个循环
//双亲在左,叔叔(存在的话)在右
if (gf->_pLeft == parent)
{
Node*uncle = gf->_pRight;
if (uncle && uncle->_color == RED) //情况一
{
parent->_color = BLACK;
uncle->_color = BLACK;
gf->_color = RED;
//向上更新
pCur = gf;
parent = pCur->_pParent;
}
else //情况二、三(将情况三转化为情况二,再一起处理)
{
if (parent->_pRight == pCur)
{
_RotateL(parent);
std::swap(parent, pCur);
}
gf->_color = RED;
parent->_color = BLACK;
_RotateR(gf);
}
}
else//双亲在右
{
Node*uncle = gf->_pLeft;
if (uncle && uncle->_color == RED) //情况一
{
parent->_color = BLACK;
uncle->_color = BLACK;
gf->_color = RED;
//向上更新
pCur = gf;
parent = pCur->_pParent;
}
else //情况二、三(将情况三转化为情况二,再一起处理)
{
if (parent->_pLeft == pCur)
{
_RotateR(parent);
std::swap(parent, pCur);
}
gf->_color = RED;
parent->_color = BLACK;
_RotateL(gf);
}
}
}
_pRoot->_color = BLACK;
return true;
}
void InOrder()
{
cout << "InOrder: ";
_InOrder(_pRoot);
cout << endl;
}
//判断是不是红黑树
bool CheckRBTree()
{
if (_pRoot == NULL)
return true;
if (_pRoot->_color == RED)//违反性质2“根结点为黑色”
return false;
size_t blackcount = 0;//统计一条链中黑色结点的数量
Node* pCur = _pRoot;
while (pCur)
{
if (pCur->_color == BLACK)
blackcount++;
pCur = pCur->_pLeft;//这里以最左边的那一条链为例
}
//验证性质4“每条链上的黑色结点都相等”,顺便验证性质3“红色结点不能相连”
return _CheckRBTree(_pRoot, blackcount, 0);
}
private:
//判断是不是红黑树(递归)
//k用来统计每一条链上的黑色结点的个数,但是不能给成引用,否则,再次统计下一条链的时候,就不会更新
bool _CheckRBTree(Node* pRoot, const size_t blackCount, size_t k)
{
if (pRoot == NULL)
return true;
if (pRoot->_color == BLACK)
k++;
Node* parent = pRoot->_pParent;
if (parent && parent->_color == RED && pRoot->_color == RED)//违反性质3
return false;
if (pRoot->_pLeft == NULL&&pRoot->_pRight == NULL)
{
if (k != blackCount)//违反性质4
return false;
}
return _CheckRBTree(pRoot->_pLeft, blackCount, k)
&& _CheckRBTree(pRoot->_pRight, blackCount, k);
}
//左旋
void _RotateL(Node* parent)
{
Node* subR = parent->_pRight;
Node* subRL = subR->_pLeft;//有可能不存在
parent->_pRight = subRL;
if (subRL)
subRL->_pParent = parent;
subR->_pLeft = parent;
Node* gparent = parent->_pParent;//保存parent的双亲
parent->_pParent = subR;
if (gparent == NULL)//parent是根结点
_pRoot = subR;
else if (gparent->_pLeft == parent)
gparent->_pLeft = subR;
else
gparent->_pRight = subR;
subR->_pParent = gparent;//第三个
}
//右旋
void _RotateR(Node* parent)
{
Node*subL = parent->_pLeft;
Node*subLR = subL->_pRight;
parent->_pLeft = subLR;
if (subLR)
subL->_pParent = parent;
subL->_pRight = parent;
Node*gparent = parent->_pParent;
parent->_pParent = subL;
subL->_pParent = gparent;
if (gparent == NULL)
_pRoot = subL;
else if (gparent->_pLeft == parent)
gparent->_pLeft = subL;
else
gparent->_pRight = subL;
}
//中序遍历
void _InOrder(Node* pRoot)
{
if (pRoot)
{
_InOrder(pRoot->_pLeft);
cout << pRoot->_key << " ";
_InOrder(pRoot->_pRight);
}
}
//获取最小节点
Node* _GetMinNode()
{
Node* pCur = _pRoot;
Node*parent = NULL;
while (pCur)
{
parent = pCur;
pCur = pCur->_pLeft;
}
return parent;
}
//获取最大节点
Node* _GetMaxNode()
{
Node* pCur = _pRoot;
Node*parent = NULL;
while (pCur)
{
parent = pCur;
pCur = pCur->_pRight;
}
return parent;
}
private:
Node* _pRoot;
};
#endif
void TestRBTree()
{
int a[] = { 10, 7, 8, 15, 5, 6, 11, 13, 12 };
RBTree<int, int> t;
for (int idx = 0; idx < sizeof(a) / sizeof(a[0]); ++idx)
t.Insert(a[idx], idx);
t.InOrder();
if (t.CheckRBTree())
{
cout << "是红黑树" << endl;
}
else
{
cout << "不是红黑树" << endl;
}
}
迭代器中给出了什么操作:
Self& operator++();
Self operator++(int);
Self& operator--();
Self operator--(int);
Ref operator*();//这里的Ref是我自己通过模板类给出的类型
const Ref operator*()const ;
Pointer operator->();
const Pointer operator->()const;
这里重点就是自增和自减的操作,我们知道红黑是是二叉搜索树,那么他的中序遍历是有序的,所以,在迭代器下,一个节点的下一个节点是它右子树的最左边的节点;同样,一个节点的上一个节点是他左子树的最右边的节点。
但是这里总有一些例外的情况,如:一个结点右子树没有左节点那么怎么处理,或是左子树没有右节点呢?
对于这两种情况我们需要特别处理,那么以第二个图来说,这是右子树没有左节点的情况,也就是自增的情况,那么我们需要将其双亲保存起来,然后向上面遍历们直到找到一个其左孩子存在为止,这时候,其就是要找的节点。
同样的,自减也是这样,不过这里需要要遭注意一个特殊的地方,就是,在头结点的位置,我们要是进行自减的话,按理说,应该是到key最大的位置,但是,我们的代码中,并不适用这个,所以,我们需要拿出来单独处理。
void _Increment()
{
//找右子树的最左边的节点
if (_pNode->_pRight)
{
_pNode = _pNode->_pRight;
while (_pNode->_pLeft)
_pNode = _pNode->_pLeft;
}
//特殊情况
else
{
Node* parent = _pNode->_pParent;
while (parent->_pRight == _pNode)
{
_pNode = parent;
parent = parent->_pParent;
}
if (parent->_pRight != _pNode)
_pNode = parent;
}
}
void _Decrement()
{
//头结点的情况:自减之后到key最大的结点
if (_pNode->_color == RED&&_pNode->_pParent->_pParent == _pNode)
_pNode = _pNode->_pRight;
//找左子树的最右边的节点
else if (_pNode->_pLeft)
{
_pNode = _pNode->_pLeft;
while (_pNode->_pRight)
_pNode = _pNode->_pRight;
}
//特殊情况处理
else
{
Node* parent = _pNode->_pParent;
while (parent->_pLeft == _pNode)
{
_pNode = parent;
parent = parent->_pParent;
}
_pNode = parent;
}
}
下面是完整的代码:
#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(), const COLOR& color = RED)
:_pLeft(NULL)
, _pRight(NULL)
, _pParent(NULL)
, _key(key)
, _value(value)
, _color(color)
{}
RBTreeNode<K, V>* _pLeft;
RBTreeNode<K, V>* _pRight;
RBTreeNode<K, V>* _pParent;
K _key;
V _value;
COLOR _color; //结点的颜色,初始值为红色
};
#if 0
template<class K, class V, class Ref, class Pointer>
class RBTreeIterator
{
typedef RBTreeNode<K, V> Node;
typedef RBTreeIterator<K, V, Ref, Pointer> Self;
public:
RBTreeIterator()
: _pNode(NULL)
{}
RBTreeIterator(Node* pNode)
: _pNode(pNode)
{}
RBTreeIterator(RBTreeIterator& it)
: _pNode(it._pNode)
{}
Self& operator++()
{
_Increment();
return *this;
}
Self operator++(int)
{
Self temp = *this;
_Increment();
return temp;
}
Self& operator--()
{
_Decrement();
return *this;
}
Self operator--(int)
{
Self temp = *this;
_Decrement();
return temp;
}
Ref operator*()
{
return _pNode->_key;
}
const Ref operator*()const
{
return _pNode->_key;
}
Pointer operator->()
{
return &(operator*());
}
const Pointer operator->()const
{
return &(operator*());
}
bool operator==(const Self& it)
{
return _pNode == it._pNode;
}
bool operator!=(const Self& it)
{
return _pNode != it._pNode;
}
protected:
void _Increment()
{
//找右子树的最左边的节点
if (_pNode->_pRight)
{
_pNode = _pNode->_pRight;
while (_pNode->_pLeft)
_pNode = _pNode->_pLeft;
}
//特殊情况
else
{
Node* parent = _pNode->_pParent;
while (parent->_pRight == _pNode)
{
_pNode = parent;
parent = parent->_pParent;
}
if (parent->_pRight != _pNode)
_pNode = parent;
}
}
void _Decrement()
{
//头结点的情况:自减之后到key最大的结点
if (_pNode->_color == RED&&_pNode->_pParent->_pParent == _pNode)
_pNode = _pNode->_pRight;
//找左子树的最右边的节点
else if (_pNode->_pLeft)
{
_pNode = _pNode->_pLeft;
while (_pNode->_pRight)
_pNode = _pNode->_pRight;
}
//特殊情况处理
else
{
Node* parent = _pNode->_pParent;
while (parent->_pLeft == _pNode)
{
_pNode = parent;
parent = parent->_pParent;
}
_pNode = parent;
}
}
protected:
Node* _pNode;
};
template<class K, class V>
class RBTree
{
typedef RBTreeNode<K, V> Node;
public:
typedef RBTreeIterator<K, V, K&, K*> Iterator;
public:
RBTree()
:_size(0)
{
_pHead = new Node(K(), V());
_pHead->_pLeft = _pHead;
_pHead->_pRight = _pHead;
_pHead->_pParent = NULL;
_pHead->_color = RED;
}
Iterator Begin()
{
return Iterator(_pHead->_pLeft);
}
Iterator End()
{
return Iterator(_pHead);//注意end的位置,不是最大的key所在结点
}
bool Empty()const
{
return _size == 0;
}
size_t Size()const
{
return _size;
}
Iterator Find(const K& key)
{
Iterator it = Begin();
while (it != End())
{
if (key == *it)
return it;
else
++it;
}
}
// 首先:搜索树
bool Insert(const K& key, const V& value)
{
Node* pRoot = _GetRoot();
if (pRoot == NULL)
{
Node* pRoot = new Node(key, value);
pRoot->_pParent = _pHead;
_pHead->_pParent = pRoot;
pRoot->_color = BLACK;
_size++;
return true;
}
//找插入位置
Node*pCur = pRoot;
Node*parent = NULL;
while (pCur)
{
if (key < pCur->_key)
{
parent = pCur;
pCur = pCur->_pLeft;
}
else if (key>pCur->_key)
{
parent = pCur;
pCur = pCur->_pRight;
}
else
return false;
}
//插入
pCur = new Node(key, value);
if (key < parent->_key)
parent->_pLeft = pCur;
else
parent->_pRight = pCur;
_size++;
pCur->_pParent = parent;//注意,不要遗漏了。。。
//看红黑树是否还满足其性质(分情况讨论)
while (pRoot != pCur && parent->_color == RED)//这个条件很重要
{
Node* gf = parent->_pParent;//保存双亲的双亲
//双亲在左,叔叔(存在的话)在右
if (gf->_pLeft == parent)
{
Node*uncle = gf->_pRight;
if (uncle && uncle->_color == RED) //情况一
{
parent->_color = BLACK;
uncle->_color = BLACK;
gf->_color = RED;
//向上更新
pCur = gf;
parent = pCur->_pParent;
}
else //情况二、三(将情况三转化为情况二,再一起处理)
{
if (parent->_pRight == pCur)
{
_RotateL(parent);
std::swap(parent, pCur);
}
gf->_color = RED;
parent->_color = BLACK;
_RotateR(gf);
}
}
else//双亲在右
{
Node*uncle = gf->_pLeft;
if (uncle && uncle->_color == RED) //情况一
{
parent->_color = BLACK;
uncle->_color = BLACK;
gf->_color = RED;
//向上更新
pCur = gf;
parent = pCur->_pParent;
}
else //情况二、三(将情况三转化为情况二,再一起处理)
{
if (parent->_pLeft == pCur)
{
_RotateR(parent);
std::swap(parent, pCur);
}
gf->_color = RED;
parent->_color = BLACK;
_RotateL(gf);
}
}
}
pRoot = _GetRoot();//旋转完成之后要再把根结点获取一遍
pRoot->_color = BLACK;
_pHead->_pLeft = _GetMinNode();
_pHead->_pRight = _GetMaxNode();
return true;
}
void InOrder()
{
cout << "InOrder: ";
_InOrder(_GetRoot());
cout << endl;
}
//判断是不是红黑树
bool CheckRBTree()
{
Node* pRoot = _GetRoot();
if (pRoot == NULL)
return true;
if (pRoot->_color == RED)//违反性质2“根结点为黑色”
return false;
size_t blackcount = 0;//统计一条链中黑色结点的数量
while (pRoot)
{
if (pRoot->_color == BLACK)
blackcount++;
pRoot = pRoot->_pLeft;//这里以最左边的那一条链为例
}
//验证性质4“每条链上的黑色结点都相等”,顺便验证性质3“红色结点不能相连”
return _CheckRBTree(pRoot, blackcount, 0);
}
private:
//判断是不是红黑树(递归)
//k用来统计每一条链上的黑色结点的个数,但是不能给成引用,否则,再次统计下一条链的时候,就不会更新
bool _CheckRBTree(Node* pRoot, const size_t blackCount, size_t k)
{
if (pRoot == NULL)
return true;
if (pRoot->_color == BLACK)
k++;
Node* parent = pRoot->_pParent;
if (parent && parent->_color == RED && pRoot->_color == RED)//违反性质3
return false;
if (pRoot->_pLeft == NULL&&pRoot->_pRight == NULL)
{
if (k != blackCount)//违反性质4
return false;
}
return _CheckRBTree(pRoot->_pLeft, blackCount, k)
&& _CheckRBTree(pRoot->_pRight, blackCount, k);
}
//左旋
void _RotateL(Node* parent)
{
Node* subR = parent->_pRight;
Node* subRL = subR->_pLeft;//有可能不存在
parent->_pRight = subRL;
if (subRL)
subRL->_pParent = parent;
subR->_pLeft = parent;
Node* gparent = parent->_pParent;//保存parent的双亲
parent->_pParent = subR;
if (gparent == _pHead)//parent是根结点
{
_pHead->_pParent = subR; //注意:这一块的根结点怎么表示
subR->_pParent = _pHead;
}
else if (gparent->_pLeft == parent)
gparent->_pLeft = subR;
else
gparent->_pRight = subR;
subR->_pParent = gparent;//第三个
}
//右旋
void _RotateR(Node* parent)
{
Node*subL = parent->_pLeft;
Node*subLR = subL->_pRight;
parent->_pLeft = subLR;
if (subLR)
subL->_pParent = parent;
subL->_pRight = parent;
Node*gparent = parent->_pParent;
parent->_pParent = subL;
subL->_pParent = gparent;
if (gparent == _pHead)
{
_pHead->_pParent = subL;
subL->_pParent = _pHead;
}
else if (gparent->_pLeft == parent)
gparent->_pLeft = subL;
else
gparent->_pRight = subL;
}
//中序遍历
void _InOrder(Node* pRoot)
{
if (pRoot)
{
_InOrder(pRoot->_pLeft);
cout << pRoot->_key << " ";
_InOrder(pRoot->_pRight);
}
}
//获取根结点
Node* &_GetRoot()
{
return _pHead->_pParent;
}
//获取最小节点
Node* _GetMinNode()
{
Node*pRoot = _pHead->_pParent;
Node*parent = NULL;
while (pRoot)
{
parent = pRoot;
pRoot = pRoot->_pLeft;
}
return parent;
}
//获取最大节点
Node* _GetMaxNode()
{
Node*pRoot = _pHead->_pParent;
Node*parent = NULL;
while (pRoot)
{
parent = pRoot;
pRoot = pRoot->_pRight;
}
return parent;
}
private:
Node* _pHead; //头结点
size_t _size;
};
#else
//无迭代器
template<class K, class V>
class RBTree
{
typedef RBTreeNode<K, V> Node;
public:
RBTree()
:_pRoot(NULL)
{}
// 首先:搜索树
bool Insert(const K& key, const V& value)
{
if (_pRoot == NULL)
{
_pRoot = new Node(key, value);
_pRoot->_color = BLACK;
return true;
}
//找插入位置
Node*pCur = _pRoot;
Node*parent = NULL;
while (pCur)
{
if (key < pCur->_key)
{
parent = pCur;
pCur = pCur->_pLeft;
}
else if (key>pCur->_key)
{
parent = pCur;
pCur = pCur->_pRight;
}
else
return false;
}
//插入
pCur = new Node(key, value);
if (key < parent->_key)
parent->_pLeft = pCur;
else
parent->_pRight = pCur;
pCur->_pParent = parent;//注意,不要遗漏了。。。
//看红黑树是否还满足其性质(分情况讨论)
while (_pRoot!=pCur && pCur->_pParent->_color == RED)
{
Node* gf = parent->_pParent;//保存双亲的双亲
//gf肯定存在,因为,如果不存在,那么parent就是根结点,是黑色的,不会进入这个循环
//双亲在左,叔叔(存在的话)在右
if (gf->_pLeft == parent)
{
Node*uncle = gf->_pRight;
if (uncle && uncle->_color == RED) //情况一
{
parent->_color = BLACK;
uncle->_color = BLACK;
gf->_color = RED;
//向上更新
pCur = gf;
parent = pCur->_pParent;
}
else //情况二、三(将情况三转化为情况二,再一起处理)
{
if (parent->_pRight == pCur)
{
_RotateL(parent);
std::swap(parent, pCur);
}
gf->_color = RED;
parent->_color = BLACK;
_RotateR(gf);
}
}
else//双亲在右
{
Node*uncle = gf->_pLeft;
if (uncle && uncle->_color == RED) //情况一
{
parent->_color = BLACK;
uncle->_color = BLACK;
gf->_color = RED;
//向上更新
pCur = gf;
parent = pCur->_pParent;
}
else //情况二、三(将情况三转化为情况二,再一起处理)
{
if (parent->_pLeft == pCur)
{
_RotateR(parent);
std::swap(parent, pCur);
}
gf->_color = RED;
parent->_color = BLACK;
_RotateL(gf);
}
}
}
_pRoot->_color = BLACK;
return true;
}
void InOrder()
{
cout << "InOrder: ";
_InOrder(_pRoot);
cout << endl;
}
//判断是不是红黑树
bool CheckRBTree()
{
if (_pRoot == NULL)
return true;
if (_pRoot->_color == RED)//违反性质2“根结点为黑色”
return false;
size_t blackcount = 0;//统计一条链中黑色结点的数量
Node* pCur = _pRoot;
while (pCur)
{
if (pCur->_color == BLACK)
blackcount++;
pCur = pCur->_pLeft;//这里以最左边的那一条链为例
}
//验证性质4“每条链上的黑色结点都相等”,顺便验证性质3“红色结点不能相连”
return _CheckRBTree(_pRoot, blackcount, 0);
}
private:
//判断是不是红黑树(递归)
//k用来统计每一条链上的黑色结点的个数,但是不能给成引用,否则,再次统计下一条链的时候,就不会更新
bool _CheckRBTree(Node* pRoot, const size_t blackCount, size_t k)
{
if (pRoot == NULL)
return true;
if (pRoot->_color == BLACK)
k++;
Node* parent = pRoot->_pParent;
if (parent && parent->_color == RED && pRoot->_color == RED)//违反性质3
return false;
if (pRoot->_pLeft == NULL&&pRoot->_pRight == NULL)
{
if (k != blackCount)//违反性质4
return false;
}
return _CheckRBTree(pRoot->_pLeft, blackCount, k)
&& _CheckRBTree(pRoot->_pRight, blackCount, k);
}
//左旋
void _RotateL(Node* parent)
{
Node* subR = parent->_pRight;
Node* subRL = subR->_pLeft;//有可能不存在
parent->_pRight = subRL;
if (subRL)
subRL->_pParent = parent;
subR->_pLeft = parent;
Node* gparent = parent->_pParent;//保存parent的双亲
parent->_pParent = subR;
if (gparent == NULL)//parent是根结点
_pRoot = subR;
else if (gparent->_pLeft == parent)
gparent->_pLeft = subR;
else
gparent->_pRight = subR;
subR->_pParent = gparent;//第三个
}
//右旋
void _RotateR(Node* parent)
{
Node*subL = parent->_pLeft;
Node*subLR = subL->_pRight;
parent->_pLeft = subLR;
if (subLR)
subL->_pParent = parent;
subL->_pRight = parent;
Node*gparent = parent->_pParent;
parent->_pParent = subL;
subL->_pParent = gparent;
if (gparent == NULL)
_pRoot = subL;
else if (gparent->_pLeft == parent)
gparent->_pLeft = subL;
else
gparent->_pRight = subL;
}
//中序遍历
void _InOrder(Node* pRoot)
{
if (pRoot)
{
_InOrder(pRoot->_pLeft);
cout << pRoot->_key << " ";
_InOrder(pRoot->_pRight);
}
}
//获取最小节点
Node* _GetMinNode()
{
Node* pCur = _pRoot;
Node*parent = NULL;
while (pCur)
{
parent = pCur;
pCur = pCur->_pLeft;
}
return parent;
}
//获取最大节点
Node* _GetMaxNode()
{
Node* pCur = _pRoot;
Node*parent = NULL;
while (pCur)
{
parent = pCur;
pCur = pCur->_pRight;
}
return parent;
}
private:
Node* _pRoot;
};
#endif
void TestRBTree()
{
int a[] = { 10, 7, 8, 15, 5, 6, 11, 13, 12 };
RBTree<int, int> t;
for (int idx = 0; idx < sizeof(a) / sizeof(a[0]); ++idx)
t.Insert(a[idx], idx);
t.InOrder();
if (t.CheckRBTree())
{
cout << "是红黑树" << endl;
}
else
{
cout << "不是红黑树" << endl;
}
}
//void TestIterator()
//{
// int a[] = { 10, 7, 8, 15, 5, 6, 11, 13, 12 };
// RBTree<int, int> t;
// for (int idx = 0; idx < sizeof(a) / sizeof(a[0]); ++idx)
// t.Insert(a[idx], idx);
// t.InOrder();
//
// RBTree<int, int>::Iterator it = t.Begin();
// while (it != t.End())
// {
// cout << *it << " ";
// ++it;
// }
//
// RBTree<int, int>::Iterator itEnd = t.End();
// --itEnd;
// cout << *itEnd << endl;
//}
int main()
{
TestRBTree();
//TestIterator();
return 0;
}