namespace Tree
{
public class RedBlackTree : BaseTree
{
public override void Insert(int v)
{
TreeNode node = InsertVal(v);
if (node.parent == null)
{
Black(node);
return;
}
Red(node);
TreeNode grand;
TreeNode uncle;
TreeNode parent;
while ((parent = node.parent) != null && IsRed(parent))
{
grand = parent.parent;
uncle = Brother(parent);
if (uncle != null && IsRed(uncle))
{
// |--24b--|
// 21r 34r
// 插入35 放在 34右边
// |--24r---|
// 21b 34b--|
// 35r
Black(parent);
Red(grand);
Black(uncle);
node = grand;
continue;
}
// |--24b
// 17r
// 插入9放在17左边,旋转
// |--17b--|
// 9r 24r
bool pl = IsLeftChild(parent);
bool nl = IsLeftChild(node);
if (pl == nl)
{
Rotate(grand, pl);
Black(parent);
}
else
{
Rotate(parent, nl);
Rotate(grand, pl);
Black(node);
}
Red(grand);
break;
}
Black(root);
}
public override bool Remove(int v)
{
TreeNode node = RemoveVal(v, out bool left);
if (node == null)
return false;
if (IsBlack(node))
{
// |--24r---|
// 21b 34b--|
// 35r
// 删除34
// |--24r---|
// 21b 35b
if (node.left != null)
Black(node.left);
else if (node.right != null)
Black(node.right);
else
RemoveAfter(node, left);
}
return true;
}
private void RemoveAfter(TreeNode node, bool left)
{
TreeNode parent;
TreeNode brother;
while ((parent = node.parent) != null)
{
brother = Child(parent, !left);
// |----------15b--|
// |--12r------| 16b(s)
// |--11b |--14b
// 删除16 满足 IsRed(brother)
if (IsRed(brother))
{
Rotate(parent, !left);
Black(brother);
Red(parent);
brother = Child(parent, !left);
// |--12b------|
// 11b |--15b
// 14r
}
if (IsBlack(brother.left) && IsBlack(brother.right))
{
// |--15--|
// 12b 16b(s)
Red(brother);
// 15是红
if (IsRed(parent))
{
// 每条线上黑色没有变化
// |--15b--|
// 12r
Black(parent);
break;
}
// 15是黑
// 15 这条线上少了一个黑色 将15当做删除点上浮
// |--15b--|
// 12r
node = parent;
left = IsLeftChild(parent);
}
else
{
// |------15b--|
// |--12b--| 16b
// 14r
if (IsBlack(Child(brother, !left)))
{
Rotate(brother, left);
brother = Child(brother, !left);
// |--15b--|
// |--14r 16b
// |--12b
}
// |--15b--|
// |--14r 16b
// |--12b
Color(brother, IsRed(parent));
Black(Child(brother, !left));
Black(parent);
Rotate(parent, !left);
// |--14r--|
// |--12b 15b
break;
}
}
}
private TreeNode Brother(TreeNode node)
{
if (node.parent == null) return null;
return Child(node.parent, node.parent.left != node);
}
private bool IsBlack(TreeNode node)
{
return node == null || !node.bRed;
}
private bool IsRed(TreeNode node)
{
return !IsBlack(node);
}
private void Black(TreeNode node)
{
Color(node, false);
}
private void Red(TreeNode node)
{
Color(node, true);
}
private void Color(TreeNode node, bool red)
{
if (node != null) node.bRed = red;
}
}
}
二叉搜索树-平衡二叉树
于 2024-05-08 17:18:27 首次发布