红黑树的节点删除:
1、如果删除的节点的孩子节点补上来是红色的,就直接将孩子涂成黑色;
2、删除节点没有红色的孩子节点时的情况
A:兄弟节点是黑色的,而且兄弟的孩子节点都是黑色的.
C.color = Color.RED;
X = A;
B:兄弟节点是黑色的,兄弟节点的孩子节点是左黑右红
A.color = C.color;
C.color = A.color;
E.color = Color.BLACK;
leftRotate(C);
C:兄弟节点是黑色的,兄弟节点的孩子节点是左红右黑
C.color = A.color;
A.color = Color.RED;
E.color = Color.RED;
leftRotate(C);
D:兄弟节点是黑色的,兄弟节点的孩子节点是左红右黑
C.color = D.color;
D.color = C.color;
rightRotate(C);
E:兄弟节点是红色的
C.color = A.color;
A.color = C.color;
lefRotate(A);
删除的代码示例:
/**
* 红黑树删除节点
* @param data
*/
public void remove(T data){
if(this.root == null)
return;
RBNode<T> cur = this.root;
while(cur != null){
if(cur.getData().compareTo(data) > 0){
cur = cur.getLeft();
} else if(cur.getData().compareTo(data) < 0){
cur = cur.getRight();
} else {
break;
}
}
if(cur == null){
return;
}
if(cur.getLeft() != null && cur.getRight() != null){
RBNode<T> old = cur;
cur = cur.getLeft();
while(cur.getRight() != null){
cur = cur.getRight();
}
old.setData(cur.getData());
}
// 删除cur指向的节点
RBNode<T> child = cur.getLeft();
if(child == null){
child = cur.getRight();
}
if(child != null){
child.setParent(cur.getParent());
if(cur.getParent() == null){
this.root = child;
} else {
if(cur.getParent().getLeft() == cur){
cur.getParent().setLeft(child);
} else {
cur.getParent().setRight(child);
}
}
if(color(cur) == Color.BLACK){
fixAfterRemove(child);
}
} else {
if(cur.getParent() == null){
this.root = null;
} else {
if(color(cur) == Color.BLACK){
fixAfterRemove(cur);
}
if(cur.getParent().getLeft() == cur){
cur.getParent().setLeft(null);
} else {
cur.getParent().setRight(null);
}
}
}
}
private void fixAfterRemove(RBNode<T> node) {
while(color(node) == Color.BLACK){
if(node == left(parent(node))){
// 左子树删除黑色节点
RBNode<T> brother = right(parent(node));
if(color(brother) == Color.RED){ // 情况4
setColor(brother, Color.BLACK);
setColor(parent(node), Color.RED);
leftRotate(parent(node));
brother = right(parent(node));
}
if(color(left(brother)) == Color.BLACK // 情况1
&& color(right(brother)) == Color.BLACK){
setColor(brother, Color.RED);
node = parent(node);
} else {
// 情况3的前半段
if(color(right(brother)) != Color.RED){
setColor(brother, Color.RED);
setColor(left(brother), Color.BLACK);
rightRotate(brother);
brother = right(parent(node));
}
// 统一处理情况2
setColor(brother, color(parent(node)));
setColor(parent(node), Color.BLACK);
setColor(right(brother), Color.BLACK);
leftRotate(parent(node));
break;
}
} else {
// 右子树删除黑色节点
RBNode<T> brother = left(parent(node));
if(color(brother) == Color.RED){ // 情况4
setColor(brother, Color.BLACK);
setColor(parent(node), Color.RED);
rightRotate(parent(node));
brother = left(parent(node));
}
if(color(left(brother)) == Color.BLACK // 情况1
&& color(right(brother)) == Color.BLACK){
setColor(brother, Color.RED);
node = parent(node);
} else {
// 情况3的前半段
if(color(left(brother)) != Color.RED){
setColor(brother, Color.RED);
setColor(right(brother), Color.BLACK);
leftRotate(brother);
brother = left(parent(node));
}
// 统一处理情况2
setColor(brother, color(parent(node)));
setColor(parent(node), Color.BLACK);
setColor(left(brother), Color.BLACK);
rightRotate(parent(node));
break;
}
}
}
// 在当前这一路遇见红色节点,直接补一个黑色节点
setColor(node, Color.BLACK);
}