目录
性质
近似平衡的二叉搜索树
最长路径不超过最短路径的两倍
1.每个结点不是黑色就是黑色
2.根节点是黑色
3.不能出现连续的红色结点(连续结点组成:红+黑 黑+红 黑+黑)
4.每条路径的黑色结点数目相同
5.叶子节点都为黑色(空结点)NIL结点
分析:
最短路径:全黑
最长路径:黑红相间
每条路径的黑色节点数相同,所以最长路径最长是最短路径的两倍,不会超过
插入规则
插入黑色结点会影响整体,所以新节点插入红色结点
1.如果插入结点的父亲是黑色,不需要处理
2.如果插入结点的父亲是红色,那么需要进行处理(1.变色 2.旋转+变色)
需要处理下还分为两种情况
1.uncle存在为红色 变色
2.uncle不存在或存在为黑色 旋转+变色
调整方法
插入在grandfather的左子树
uncle存在为红色(变色)
只需要将p和u变为黑色,g变为红色,然后令c=g继续往上调整
1.插入在parent的左侧
2.插入在parent的右侧
uncle不存在或存在为黑色(旋转+变色)
插入在parent的左边
单纯变色无法完成调整,我们需要先进行右单旋再进行变色
1.uncle不存在
2.uncle存在且为黑
代码
插入在parent的右边
类别于AVL树,这里需要进行双旋再变色
1.uncle不存在
2.uncle存在且为黑
这种情况肯定是由这种情况变色而造成
(f的左子树里必含有一个黑色节点)
进行旋转
变色
代码
插入在grandfather的右子树
uncle存在且为红色(变色)
1.插入在parent的右边
2.插入在parent的左边‘’
代码
uncle不存在或者存在为黑色(旋转+变色)
插入在parent的右侧
1.uncle不存在
2.uncle存在且为黑色
代码
插入在parent的左侧
1.uncle不存在
2.uncle存在且为黑色
代码
整体分析
创建结点
插入
插入新节点是红色
插入分为两种情况
1.父节点为黑色不做处理
2.父节点为红色
又分为两种情况(见调整方法)
判断是否为红黑树
完整代码
#pragma once
enum Colour
{
RED,
BLACK
};
template<class K, class V>
struct RBTreeNode
{
RBTreeNode<K, V>* _left;
RBTreeNode<K, V>* _parent;
RBTreeNode<K, V>* _right;
pair<K, V> _kv;
Colour _col;
RBTreeNode(const pair<K, V>& kv)
:_left(nullptr)
,_parent(nullptr)
,_right(nullptr)
,_kv(kv)
,_col(RED)
{ }
};
template<class K,class V>
class RBTree
{
typedef RBTreeNode<K, V> Node;
public:
bool Insert(const pair<K, V>& kv)
{
if (_root == nullptr)
{
_root = new Node(kv);
_root->_col = BLACK;
return true;
}
Node* cur = _root;
Node* parent = nullptr;
//寻找插入位置
while (cur)
{
if (cur->_kv.first > kv.first)
{
parent = cur;
cur = cur->_left;
}
else if (cur->_kv.first < kv.first)
{
parent = cur;
cur = cur->_right;
}
else
{
return false;
}
}
//插入
cur = new Node(kv);
if (parent->_kv.first > kv.first)
{
parent->_left = cur;
}
else
{
parent->_right = cur;
}
cur->_parent = parent;
//调整
//1.父亲为黑不需要调整
//2.父亲为红需要调整
while (parent && parent->_col == RED)
{
Node* grandfather = parent->_parent;
//新增结点在左子树
// g
// p u
// c
if (parent == grandfather->_left)
{
//1.uncle存在且为红色
Node* uncle = grandfather->_right;
if (uncle && uncle->_col == RED)
{
//变色
parent->_col = uncle->_col = BLACK;
grandfather->_col = RED;
//继续向上处理
cur = grandfather;
parent = cur->_parent;
}
//2.uncle不存在或uncle存在且为黑色
// g
// p
// c
else
{
if (cur == parent->_left)
{
RotateR(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
else
{
//旋转
RotateL(parent);
RotateR(grandfather);
//变色
grandfather->_col = RED;
cur->_col = BLACK;
}
break;
}
}
else
{
//1.uncle存在且为红色
Node* uncle = grandfather->_left;
if (uncle && uncle->_col == RED)
{
//变色
parent->_col = uncle->_col = BLACK;
grandfather->_col = RED;
//继续向上处理
cur = grandfather;
parent = cur->_parent;
}
//uncle不存在或者存在且为黑
else
{
//插入在parent的右边
if (cur == parent->_right)
{
RotateL(grandfather);
grandfather->_col = RED;
parent->_col = BLACK;
}
else
{
RotateR(parent);
RotateL(grandfather);
grandfather->_col = RED;
cur->_col = BLACK;
}
break;
}
}
}
_root->_col = BLACK;
return true;
}
void RotateR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
parent->_left = subLR;
subL->_right = parent;
Node* parentparent = parent->_parent;
if (subLR)
subLR->_parent = parent;
parent->_parent = subL;
if (_root == parent)
{
_root = subL;
subL->_parent = nullptr;
}
else
{
if (parentparent->_left == parent)
{
parentparent->_left = subL;
}
else
{
parentparent->_right = subL;
}
subL->_parent = parentparent;
}
}
void RotateL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
parent->_right = subRL;
subR->_left = parent;
Node* parentparent = parent->_parent;
if (subRL)
subRL->_parent = parent;
parent->_parent = subR;
if (_root == parent)
{
_root = subR;
subR->_parent = nullptr;
}
else
{
if (parentparent->_left == parent)
{
parentparent->_left = subR;
}
else
{
parentparent->_right = subR;
}
subR->_parent = parentparent;
}
}
bool IsBalance()
{
return _IsBalance(_root);
}
bool _IsBalance(Node* root)
{
if (root == nullptr)
{
return true;
}
if (root->_col != BLACK)
{
return false;
}
Node* cur = _root;
int benmark = 0;
while (cur)
{
if (cur->_col == BLACK)
{
++benmark;
}
cur = cur->_left;
}
return _IsValidRBTRee(_root, 0, benmark);
}
bool _IsValidRBTRee(Node* root, int blacknum, int benmark)
{
if (root == nullptr)
{
if (blacknum != benmark)
{
return false;
}
return true;
}
if (root->_col == BLACK)
{
++blacknum;
}
if (root->_col == RED && root->_parent->_col == RED)
{
cout << "连续红结点" << endl;
return false;
}
return _IsValidRBTRee(root->_left, blacknum, benmark)
&& _IsValidRBTRee(root->_right, blacknum, benmark);
}
int Size()
{
return _Size(_root);
}
int _Size(Node* root)
{
if (root == nullptr)
{
return 0;
}
return _Size(root->_left) + _Size(root->_right) + 1;
}
void Inorder()
{
_Inorder(_root);
cout << endl;
}
void _Inorder(Node* root)
{
if (root == nullptr)
{
return;
}
_Inorder(root->_left);
cout << root->_kv.first << ' ';
_Inorder(root->_right);
}
private:
Node* _root = nullptr;
};
测试代码