1.什么是2-3数
2.什么是红黑树
红黑树的简单框架:
class RBT1<E> where E : IComparable<E>
{
private const bool Red = true;
private const bool Black = false;
private class Node
{
public E e;
public Node left;
public Node right;
public bool color;
public Node(E e)
{
this.e = e;
left = null;
right = null;
color = Red;
}
}
private Node root;
private int N;
public RBT1()
{
root = null;
N = 0;
}
public int Count { get { return N; } }
public bool IsEmpty { get { return N == 0; } }
private bool IsRed(Node node)
{
if (node == null)
return Black;
return node.color;
}
}
3.左旋转
// node x
// / \ 左旋转 / \
// T1 x ---------> node T3
// / \ / \
// T2 T3 T1 T2
//返回左旋转后新的二叉查找树的根
private Node LeftRotate(Node node)
{
Node x = node.right;
node.right = x.left;
x.left = node;
x.color = node.color;
node.color = Red; //node.color对应2-3树中的3节点,所以一定是红色的
return x;
}
4.颜色反转和右旋转
颜色反转:
若node10为根节点,则一定是黑色。
private void FlipColors(Node node)
{
node.color = Red;
node.left.color = Black;
node.right.color = Black;
}
右旋转:
将node.color赋给x.color,将node.color设为红色;
颜色反转;
判断x为根节点,变为黑色。
// node x
// / \ 右旋转 / \
// x T2 -------> T3 node
// / \ / \
// T3 T1 T1 T2
//返回右旋转后新的二叉查找树的根,对新的二叉查找树进行后续的修复操作
//右旋转过程中保证二叉树的性质,左子树都比根节点小,右子树都比根节点大
private Node RightRotate(Node node)
{
Node x = node.left;
node.left = x.right;
x.right = node;
x.color = node.color;
node.color = Red;
return x;
}
5.添加、包含、最大高度
添加:
//往红黑树中添加元素,递归实现
public void Add(E e)
{
root = Add(root, e);
root.color = Black;
}
//以node为根的树中添加元素e,添加后返回根节点node
private Node Add(Node node, E e)
{
if (node == null)
{
N++;
return new Node(e); //默认为红结点
}
if (e.CompareTo(node.e) < 0)
node.left = Add(node.left, e);
else if (e.CompareTo(node.e) > 0)
node.right = Add(node.right, e);
//如果出现右子结点是红色,而左子结点是黑色,进行左旋转
if (IsRed(node.right) && !IsRed(node.left))
LeftRotate(node);
//如果出现连续的左子节点都是红色,进行右旋转
if (IsRed(node.left) && IsRed(node.left.left))
node = RightRotate(node);
//如果出现左右子节点均为红色,进行颜色反转
if (IsRed(node.left) && IsRed(node.right))
FlipColors(node);
return node;
}
包含(与二叉查找树相同):
//查询红黑树是否包含元素e
public bool Contains(E e)
{
return Contains(root, e);
}
//以node为根的树是否包含元素e
private bool Contains(Node node, E e)
{
if (node == null)
return false;
if (e.CompareTo(node.e) == 0)
return true;
else if (e.CompareTo(node.e) < 0)
return Contains(node.left, e);
else
return Contains(node.right, e);
}
最大高度(与二叉查找树相同):
//红黑树的最大高度
public int MaxHeigh()
{
return MaxHeigh(root);
}
//计算以node为根的红黑树的最大高度
private int MaxHeigh(Node node)
{
if (node == null)
return 0;
int l = MaxHeigh(node.left);
int r = MaxHeigh(node.right);
return Math.Max(l, r) + 1;
}
测试:
class Program
{
static void Main(string[] args)
{
RBT1<int> rbt = new RBT1<int>();
int[] a = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (int i = 0; i < a.Length; i++)
rbt.Add(a[i]);
Console.WriteLine(rbt.MaxHeigh());
Console.Read();
}
}