红黑树代码只实现了插入和删除,查找与二叉查找树相同。直接运行RBTreeTest即可测试红黑树。
红黑树代码
public class RBTree<T extends Comparable<T>> {
private static final boolean RED = true;
private static final boolean BLACK = false;
private Node<T> root;
public Node<T> getRoot() {
return root;
}
public void insert(T key) {
// 根节点,直接插入
if (root == null) {
root = new Node<>(key);
} else {
// 当前循环节点
Node<T> x = root;
// 最后一个循环的节点
Node<T> p = x;
while (x != null) {
p = x;
int tmp = key.compareTo(x.key);
// key比x大,插入到右子树
if (tmp > 0) {
x = x.right;
} else if (tmp < 0) {
// key比x小,插入到左子树
x = x.left;
} else {
// 相等节点进行替换,只不过目前没有不需要设置值,直接返回
return;
}
}
// p为待插入节点的父节点
Node<T> node = new Node<>(key);
if (key.compareTo(p.key) > 0) {
p.right = node;
} else {
p.left = node;
}
node.parent = p;
// 进行插入平衡
insertBalance(node);
}
// 根节点染黑
setBlack(root);
}
private void insertBalance(Node<T> x) {
for (; ; ) {
// 情景1:x节点为root,直接返回
if (parentOf(x) == null) {
root = x;
return;
}
// 情景2:父节点是黑色 ==> 不用处理
if (isBlack(parentOf(x))) {
return;
}
// 情景3:父节点是红色,叔节点是红色 ==> 父节点和叔节点变成黑色,祖父节点变红,x指向祖父节点
if (isRed(uncleOf(x))) {
setBlack(parentOf(x));
setBlack(uncleOf(x));
setRed(gParentOf(x));
x = gParentOf(x);
}
// 情景4:父节点红色,叔节点黑色
else {
// p是祖父节点的左子节点
if (parentOf(x) == gParentOf(x).left) {
// 情景4.1:x是p的右子节点
if (x == parentOf(x).right) {
// 以p为节点进行左旋,并且x指向p
rotateLeft(x = parentOf(x));
}
// 情景4.2:x是p的左子节点 => p变黑,x祖父变红,祖父右旋
setBlack(parentOf(x));
setRed(gParentOf(x));
rotateRight(gParentOf(x));
} else {
// p是祖父节点的右子节点
// 情景4.1:x是p的左子节点
if (x == parentOf(x).left) {
// 以p为节点进行右旋,并且x指向p
rotateRight(x = parentOf(x));
}
// 情景4.2:x是p的右子节点 => p变黑,x祖父变红,祖父左旋
setBlack(parentOf(x));
setRed(gParentOf(x));
rotateLeft(gParentOf(x));
}
}
}
}
public void delete(T key) {
// 指向待删除节点
Node<T> x = root;
while (x != null) {
int tmp = key.compareTo(x.key);
if (tmp > 0)</