红黑树相当于4阶b树
import java.util.Comparator;
public class RBTree<E> extends BBST<E> {
private static final boolean RED = false;
private static final boolean BLACK = true;
public RBTree() {
this(null);
}
public RBTree(Comparator<E> comparator) {
super(comparator);
}
/**
* 1 添加的节点 都是添加在叶子节点上 度为0
* 2 添加的节点默认是红色
* 3 添加的节点父节点是black 那么就无需关注
* 4 添加的节点父节点是red 当uncle节点为black的时候
* 当添加的节点是父节点同侧的时候 将grand染红 parent 染黑 然后对grand左旋或者右旋
* 当添加的节点与父节点异侧的时候 将parent 染红 grand染红 自己染黑 然后对rl lr处理
* 5 当添加的节点父节点是red 当uncle节点为red的时候
* 证明 grand是black 有3个节点了已经 2-3-4树 最多3个 所以需要向上合并 节点进行分裂
* 于是 将parenth和uncle染黑 grand染红向上合并
* @param node
*/
@Override
protected void afterAdd(Node<E> node) {
Node<E> parent = node.parent;
// 添加的是根节点 或者 上溢到达了根节点
if (parent == null) {
black(node);
return;
}
// 如果父节点是黑色,直接返回
if (isBlack(parent)) return;
// 叔父节点
Node<E> uncle = parent.sibling();
// 祖父节点
Node<E> grand = red(parent.parent);
if (isRed(uncle)) { // 叔父节点是红色【B树节点上溢】
black(parent);
black(uncle);
// 把祖父节点当做是新添加的节点
afterAdd(grand);
return;
}
// 叔父节点不是红色
if (parent.isLeftChild()) { // L
if (node.isLeftChild()) { // LL
black(parent);
} else { // LR
black(node);
rotateLeft(parent);
}
rotateRight(grand);
} else { // R
if (node.isLeftChild()) { // RL
black(node);
rotateRight(parent);
} else { // RR
black(parent);
}
rotateLeft(grand);
}
}
/**
* B 树中 真正被删除的就是叶子节点
* 1 删除的节点是红节点 直接删除 无需处理 对应b树 节点>1
* 2 删除的节点是black节点
* 分为 black叶子节点 带一个red节点的black节点 带2个red节点的black节点
* 当为带一个red节点的black节点 将子节点染黑
* 当为带2个red节点的black节点 会找到他的替代品 所以无需关注
* 当为black叶子节点的时候 看旁边节点是否能借 借完是否需要下溢
*
* 1 当sibling为black的时候
* 当带一个red节点的时候 进行旋转 继承parent的颜色 并且节点左右变黑 这时候看需要旋转几次 看图就能明白
* 当不带red节点的时候 就看父节点是红是黑 是红的话 将sibling染红 父节点染黑
* 如果父节点也是黑的 父节点就会下溢
* 2 当sibling为red的时候 将silbling旋转 自己染黑 父节点染红 就又回到了上面的情况
*
* @param node
*/
@Override
protected void afterRemove(Node<E> node) {
// 如果删除的节点是红色
// 或者 用以取代删除节点的子节点是红色
if (isRed(node)) {
return;
}
Node<E> replace = node.left!=null?node.left:node.right;
if(replace!=null&&node.replaceFlag){
black(replace);
return;
}
Node<E> parent = node.parent;
// 删除的是根节点
if (parent == null) return;
// 删除的是黑色叶子节点【下溢】
// 判断被删除的node是左还是右
boolean left;
if(node.uploadFlag){
left = node.isLeftChild();
}else{
left = parent.left == null;
}
Node<E> sibling = left ? parent.right : parent.left;
if (left) { // 被删除的节点在左边,兄弟节点在右边
if (isRed(sibling)) { // 兄弟节点是红色
black(sibling);
red(parent);
rotateLeft(parent);
// 更换兄弟
sibling = parent.right;
}
// 兄弟节点必然是黑色
if (isBlack(sibling.left) && isBlack(sibling.right)) {
// 兄弟节点没有1个红色子节点,父节点要向下跟兄弟节点合并
boolean parentBlack = isBlack(parent);
red(sibling);
if (parentBlack) {
parent.uploadFlag = true;
afterRemove(parent);
}
black(parent);
} else { // 兄弟节点至少有1个红色子节点,向兄弟节点借元素
// 兄弟节点的左边是黑色,兄弟要先旋转
if (isBlack(sibling.right)) {
rotateRight(sibling);
sibling = parent.right;
}
color(sibling, colorOf(parent));
black(sibling.right);
black(parent);
rotateLeft(parent);
}
} else { // 被删除的节点在右边,兄弟节点在左边
if (isRed(sibling)) { // 兄弟节点是红色
black(sibling);
red(parent);
rotateRight(parent);
// 更换兄弟
sibling = parent.left;
}
// 兄弟节点必然是黑色
if (isBlack(sibling.left) && isBlack(sibling.right)) {
// 兄弟节点没有1个红色子节点,父节点要向下跟兄弟节点合并
boolean parentBlack = isBlack(parent);
red(sibling);
if (parentBlack) {
parent.uploadFlag = true;
afterRemove(parent);
}
black(parent);
} else { // 兄弟节点至少有1个红色子节点,向兄弟节点借元素
// 兄弟节点的左边是黑色,兄弟要先旋转
if (isBlack(sibling.left)) {
rotateLeft(sibling);
sibling = parent.left;
}
color(sibling, colorOf(parent));
black(sibling.left);
black(parent);
rotateRight(parent);
}
}
}
// protected void afterRemove(Node<E> node, Node<E> replacement) {
// // 如果删除的节点是红色
// if (isRed(node)) return;
//
// // 用以取代node的子节点是红色
// if (isRed(replacement)) {
// black(replacement);
// return;
// }
//
// Node<E> parent = node.parent;
// // 删除的是根节点
// if (parent == null) return;
//
// // 删除的是黑色叶子节点【下溢】
// // 判断被删除的node是左还是右
// boolean left = parent.left == null || node.isLeftChild();
// Node<E> sibling = left ? parent.right : parent.left;
// if (left) { // 被删除的节点在左边,兄弟节点在右边
// if (isRed(sibling)) { // 兄弟节点是红色
// black(sibling);
// red(parent);
// rotateLeft(parent);
// // 更换兄弟
// sibling = parent.right;
// }
//
// // 兄弟节点必然是黑色
// if (isBlack(sibling.left) && isBlack(sibling.right)) {
// // 兄弟节点没有1个红色子节点,父节点要向下跟兄弟节点合并
// boolean parentBlack = isBlack(parent);
// black(parent);
// red(sibling);
// if (parentBlack) {
// afterRemove(parent, null);
// }
// } else { // 兄弟节点至少有1个红色子节点,向兄弟节点借元素
// // 兄弟节点的左边是黑色,兄弟要先旋转
// if (isBlack(sibling.right)) {
// rotateRight(sibling);
// sibling = parent.right;
// }
//
// color(sibling, colorOf(parent));
// black(sibling.right);
// black(parent);
// rotateLeft(parent);
// }
// } else { // 被删除的节点在右边,兄弟节点在左边
// if (isRed(sibling)) { // 兄弟节点是红色
// black(sibling);
// red(parent);
// rotateRight(parent);
// // 更换兄弟
// sibling = parent.left;
// }
//
// // 兄弟节点必然是黑色
// if (isBlack(sibling.left) && isBlack(sibling.right)) {
// // 兄弟节点没有1个红色子节点,父节点要向下跟兄弟节点合并
// boolean parentBlack = isBlack(parent);
// black(parent);
// red(sibling);
// if (parentBlack) {
// afterRemove(parent, null);
// }
// } else { // 兄弟节点至少有1个红色子节点,向兄弟节点借元素
// // 兄弟节点的左边是黑色,兄弟要先旋转
// if (isBlack(sibling.left)) {
// rotateLeft(sibling);
// sibling = parent.left;
// }
//
// color(sibling, colorOf(parent));
// black(sibling.left);
// black(parent);
// rotateRight(parent);
// }
// }
// }
private Node<E> color(Node<E> node, boolean color) {
if (node == null) return node;
((RBNode<E>)node).color = color;
return node;
}
private Node<E> red(Node<E> node) {
return color(node, RED);
}
private Node<E> black(Node<E> node) {
return color(node, BLACK);
}
private boolean colorOf(Node<E> node) {
return node == null ? BLACK : ((RBNode<E>)node).color;
}
private boolean isBlack(Node<E> node) {
return colorOf(node) == BLACK;
}
private boolean isRed(Node<E> node) {
return colorOf(node) == RED;
}
@Override
protected Node<E> createNode(E element, Node<E> parent) {
return new RBNode<>(element, parent);
}
private static class RBNode<E> extends Node<E> {
boolean color = RED;
public RBNode(E element, Node<E> parent) {
super(element, parent);
}
@Override
public String toString() {
String str = "";
if (color == RED) {
str = "R_";
}
return str + element.toString();
}
}
}
http://520it.com/binarytrees/ 推荐用这个链接 添加后一个个删除 自己先过一遍删除过程再一个个验证结果
static void test4() {
Integer data[] = new Integer[] {
55, 87, 56, 74, 96, 22, 62, 20, 70, 68, 90, 50
};
RBTree<Integer> rb = new RBTree<>();
for (int i = 0; i < data.length; i++) {
rb.add(data[i]);
}
BinaryTrees.println(rb);
for (int i = 0; i < data.length; i++) {
rb.remove(data[i]);
System.out.println("---------------------------------------");
System.out.println("【" + data[i] + "】");
BinaryTrees.println(rb);
}
}
public static void main(String[] args) {
test4();
}