除AVL树外,还有RBtree也是经常用到的平衡二叉搜索树
RBtree必须满足以下四条规则:
1.每个节点不是红色就是黑色
2.根节点为黑色
3.如果一个节点是红色,则它的 子节点是黑色的(即没有连续的红节点)
4.任一节点至NULL(树尾端)的任何路径,所含黑节点数必须相同
那AVL和RBtree有什么区别
AVltree 是严格平衡的二叉搜索树,其复杂度接近lgN,旋转多,维护起来麻烦,但是更加直观
RBree 是近似平衡的二叉搜索树,其复杂度一定小于2*(LgN),但是曾有人做过大量试验证明,红黑树的效率仍能达到lgN,旋转则较少,维护起来简单,今后项目什么的一定会优先RBtree,其比较抽象
插入操作
注意:cur为当前节点 P为父节点 g为祖父节点 u为父亲的兄弟节点即叔叔节点
状况1:该树为空树,直接插入根结点的位置,违反性质1,把节点颜色有红改为黑即可。
状况2:插入节点N的父节点P为黑色,不违反任何性质,无需做任何修改。
接下来是真正需要调整的状况了
状况3:当cur为红,P为红,g为黑,u存在且为红
先将p,u变为黑色,g改成红,然后把cur给g,继续向上搜索
状况4: cur为红,P为红,g为黑,u不存在/u为黑(cur为p的左节点)
状态5:cur为红,P为红,g为黑,u不存在/u为黑(cur为p的右节点)
p为g的左孩子,cur为p的右孩子,则针对p做左单旋转;相反,p为g的右孩子,cur为p的左孩子,则针对p做右单旋转,则转换成了情况2
删除操作
状况1:cur的兄弟b是红色的。
情况2:cur的兄弟b是黑色的,且cur的俩个孩子都是黑色的。
b变为红色后经过b节点的路径的黑节点数目也减少了1,那个从P出发到其叶子节点到所有路径所包含的黑节点数目相等了。但是这个数目比之前少了1,因为左右子树中的黑节点数目都减少了。P是他父节点g的一个孩子,那么由g到其叶子节点的黑节点数目就不相等了,所以说没有结束,需把P当做新的起始点开始向上检索。
情形3:P为红(S一定为黑),S的孩子们都为黑。
情形4:P任意色,b为黑,cur是P的左孩子,b的右孩子bR为红,b的左孩子任意(或者是cur是P的右孩子,b的左孩子为红,b的右孩子任意)。
P、b旋转有变色,等于给cur这边加了一个黑节点,P位置(是位置而不是P)的颜色不变,b这边少了一个黑节点;bR有红变黑,b这边又增加了一个黑节点;这样一来又恢复了平衡
情形5:P任意色,b为黑,cur是P的左孩子,b的左孩子bL为红,b的右孩子bR为黑(或者cur是P的右孩子,b的右孩子为红,b的左孩子为黑)。
这如果你按情形4的操作的话,由于bR本来就是黑色,无法弥补由于P、b的变换(旋转)给b这边造成的损失!所以没先对b、SL进行变换之后就变为情形4的情况了
#pragma once
#include<stdio.h>
#include<iostream>
using namespace std;
enum Color
{
RED,
BLACK,
};
template<class K, class V>
struct RBTreeNode
{
RBTreeNode<K, V>* _left;
RBTreeNode<K, V>* _right;
RBTreeNode<K, V>* _parent;
K _key;
V _value;
Color _col;
RBTreeNode(const K& key, const V& value)
:_left(NULL)
, _right(NULL)
, _parent(NULL)
, _key(key)
, _value(value)
, _col(RED)
{}
};
template<class K,class V>
class RBTree
{
typedef RBTreeNode<K,V> Node;
public:
RBTree()
:_root(NULL)
{}
bool Insert(const K& key,const V& value)
{
if (_root == NULL)
{
_root = new Node(key,value);
_root->_col = BLACK;
return true;
}
Node* parent = NULL;
Node* cur = _root;
while (cur)
{
if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else
{
return false;
}
}
//找到插入位置
cur = new Node(key, value);
if (parent->_key < key)
{
parent->_right = cur;
cur->_parent = parent;
}
else
{
parent->_left = cur;
cur->_parent = parent;
}
while (parent&&parent->_col == RED)
{
Node* grandparent = parent->_parent;
if (parent == grandparent->_left)
{
Node* uncle = grandparent->_right;
if (uncle&&uncle->_col == RED)
{
parent->_col = BLACK;
uncle->_col = BLACK;
grandparent->_col = RED;
cur = grandparent;
parent = cur->_parent;
}
else //uncle不存在,或uncle为黑色
{
if (cur == parent->_right)
{
RotateL(parent);
swap(parent,cur);
}
RotateR(grandparent);
parent->_col = BLACK;
grandparent->_col = RED;
break;
}
}
else//parent == grandparent->_right
{
Node* uncle = grandparent->_left;
if (uncle&&uncle->_col == RED)
{
parent->_col = BLACK;
uncle->_col = BLACK;
grandparent->_col = RED;
}
else//uncle不存在或者为黑色
{
if (cur == parent->_left)
{
RotateR(parent);
swap(parent, cur);
}
RotateL(grandparent);
parent->_col = BLACK;
grandparent->_col = RED;
break;
}
}
}
_root->_col = BLACK;
return true;
}
void RotateL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
parent->_right = subRL;
if (subRL)
{
subRL->_parent = parent;
}
subR->_left = parent;
Node* parentparent = parent->_parent;
parent->_parent = subR;
if (parentparent==NULL)
{
_root = subR;
}
else
{
if (parent == parentparent->_left)
{
parentparent->_left = subR;
subR->_parent = parentparent;
}
else
{
parentparent->_right = subR;
subR->_parent = parentparent;
}
}
}
void RotateR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
parent->_left = subLR;
if (subLR)
{
subLR->_parent = parent;
}
subL->_right = parent;
Node* parentparent = parent->_parent;
parent->_parent = subL;
if (parentparent == NULL)
{
_root = subL;
_root->_parent = NULL;
}
else
{
if (parent == parentparent->_left)
{
parentparent->_left = subL;
subL->_parent = parentparent;
}
else
{
parentparent->_right = subL;
subL->_parent = parentparent;
}
}
}
void InOrder()
{
_InOrder(_root);
cout << endl;
}
void _InOrder(Node* root)
{
if (root == NULL)
return;
_InOrder(root->_left);
cout<<root->_key<<" ";
_InOrder(root->_right);
}
bool IsBalance()
{
if (_root == NULL)
{
return true;
}
if (_root&&_root->_col==RED)
{
return false;
}
int BlackNum = 0;
Node* left = _root;
while (left)
{
if (left->_col == BLACK)
{
++BlackNum;
}
left = left->_left;
}
int num = 0;
return _IsBalance(_root, num, BlackNum);
}
bool _IsBalance(Node* root, int num, const int blackNum)
{
if (root == NULL)
{
return true;
}
if (root->_col == RED&&root->_parent->_col == RED)
{
cout<<"存在连续的红节点"<<root->_key<<endl;
return false;
}
if (root->_col == BLACK)
{
++num;
}
// num 是根节点到当前节点黑色节点的数量
if (root->_left == NULL && root->_right == NULL)
{
if (num != blackNum)
{
//cout<<"黑色节点的数量不相等"<<root->_key<<endl;
return false;
}
else
{
return true;
}
}
return _IsBalance(root->_left, num, blackNum)
&& _IsBalance(root->_right, num, blackNum);
}
private:
Node* _root;
};
void TestRBTree()
{
RBTree<int, int> t;
int a[] = {16, 3, 7, 11, 9, 26, 18, 14, 15};
//int a[] = {4, 2, 6, 1, 3, 5, 15, 7, 16, 14};
for (size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i)
{
t.Insert(a[i], i);
}
t.InOrder();
cout<<"IsBalance?"<<t.IsBalance()<<endl;
}