目录
性质
插入规则
调整方法
插入在grandfather的左子树
uncle存在为红色(变色)
uncle不存在或存在为黑色(旋转+变色)
插入在grandfather的右子树
uncle存在且为红色(变色)
uncle不存在或者存在为黑色(旋转+变色)
整体分析
完整代码
近似平衡的二叉搜索树
最长路径不超过最短路径的两倍
1.每个结点不是黑色就是黑色
2.根节点是黑色
3.不能出现连续的红色结点(连续结点组成:红+黑 黑+红 黑+黑)
4.每条路径的黑色结点数目相同
5.叶子节点都为黑色(空结点)NIL结点
分析:
最短路径:全黑
最长路径:黑红相间
每条路径的黑色节点数相同,所以最长路径最长是最短路径的两倍,不会超过
插入黑色结点会影响整体,所以新节点插入红色结点
1.如果插入结点的父亲是黑色,不需要处理
2.如果插入结点的父亲是红色,那么需要进行处理(1.变色 2.旋转+变色)
需要处理下还分为两种情况
1.uncle存在为红色 变色
2.uncle不存在或存在为黑色 旋转+变色
只需要将p和u变为黑色,g变为红色,然后令c=g继续往上调整
1.插入在parent的左侧
2.插入在parent的右侧
插入在parent的左边
单纯变色无法完成调整,我们需要先进行右单旋再进行变色
1.uncle不存在
2.uncle存在且为黑
代码
插入在parent的右边
类别于AVL树,这里需要进行双旋再变色
1.uncle不存在
2.uncle存在且为黑
这种情况肯定是由这种情况变色而造成
(f的左子树里必含有一个黑色节点)
进行旋转
变色
代码
1.插入在parent的右边
2.插入在parent的左边‘’
代码
插入在parent的右侧
1.uncle不存在
2.uncle存在且为黑色
代码
插入在parent的左侧
1.uncle不存在
2.uncle存在且为黑色
代码
创建结点
插入
插入新节点是红色
插入分为两种情况
1.父节点为黑色不做处理
2.父节点为红色
又分为两种情况(见调整方法)
判断是否为红黑树
#pragma once
enum Colour
{
RED,
BLACK
};
template
struct RBTreeNode
{
RBTreeNode* _left;
RBTreeNode* _parent;
RBTreeNode* _right;
pair _kv;
Colour _col;
RBTreeNode(const pair& kv)
:_left(nullptr)
,_parent(nullptr)
,_right(nullptr)
,_kv(kv)
,_col(RED)
{ }
};
template
class RBTree
{
typedef RBTreeNode Node;
public:
bool Insert(const pair& 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;
};
测试代码