插入:
向二节点插:直接插入
向三节点插:三个节点构成三角,直接插
三个节点构成直线,变色旋转一次
三个节点构成折线,变色一次,旋转两次
向四节点插:父辈节点变黑,爷爷节点变红
/**
* 对插入的节点进行调整
* @param node
*/
private void fixAfterPut(Node<K,V> node) {
//node的父节点是爷爷的左孩子
while (node.parent != null && node.parent.color == RED) {
if(parentOf(node) == leftOf(parentOf(parentOf(node)))) {
Node uncle = parentOf(parentOf(node)).right;
if(colorOf(uncle) == RED) {
setColor(parentOf(node), BLACK);
setColor(uncle, BLACK);
node = parentOf(parentOf(node));
if(node != root) {
setColor(node, RED);
}
} else {
if(rightOf(parentOf(node)) == node) {
node = parentOf(node);
leftRotate(node);
}
setColor(parentOf(node), BLACK);
setColor(parentOf(parentOf(node)), RED);
rightRotate(parentOf(parentOf(node)));
}
} else {
//node的父节点是爷爷的右孩子
Node uncle = parentOf(parentOf(node)).left;
if(colorOf(uncle) == RED) {
setColor(parentOf(node), BLACK);
setColor(uncle, BLACK);
node = parentOf(parentOf(node));
if(node != root) {
setColor(node, RED);
}
} else {
if(leftOf(parentOf(node)) == node) {
node = parentOf(node);
rightRotate(node);
}
setColor(parentOf(node), BLACK);
setColor(parentOf(parentOf(node)), RED);
leftRotate(parentOf(parentOf(node)));
}
}
}
}
删除:若被删除节点有两个子节点,找其前驱或后继节点替代
若删除的节点对应234树是三节点或四节点删除,红色直接删除,黑色则找其子节点代替变黑
若删除的节点对应234树是二节点删除,需要调整,找到真正的兄弟节点,向兄弟节点借节点平衡黑色
若兄弟有1个子节点,该子节点与兄弟与父节点构成直线,直接变色旋转,若构成折线,需变色旋转两次。若兄弟有2个子节点,直接变色旋转。
若兄弟无子节点,兄弟变红,若父亲为红色,父亲变黑维持平衡结束,否则父亲向其兄弟借,借到平衡结束,否则父亲兄弟变黑,重复此过程
二节点删除调整代码:
private void fixAfterRemove(Node node) {
while (colorOf(node) != RED && node != root) {
//node为左孩子
if (node == leftOf(node.parent)) {
Node brother = rightOf(node.parent);
if (colorOf(brother) == RED) {
setColor(brother, BLACK);
setColor(parentOf(node), RED);
leftRotate(parentOf(node));
brother = rightOf(parentOf(node));
}
//兄弟节点有孩子节点
if (colorOf(leftOf(brother)) == BLACK && colorOf(rightOf(brother)) == BLACK) {
setColor(brother, RED);
node = node.parent;
} else {
if (leftOf(brother) != null && rightOf(brother) == null) {
setColor(brother, RED);
setColor(brother.left, BLACK);
rightRotate(brother);
brother = rightOf(parentOf(node));
}
setColor(brother, colorOf(parentOf(node)));
setColor(rightOf(brother), BLACK);
setColor(parentOf(node), BLACK);
leftRotate(parentOf(node));
node = root;
}
} else {
Node brother = leftOf(node.parent);
if (colorOf(brother) == RED) {
setColor(brother, BLACK);
setColor(parentOf(node), RED);
rightRotate(parentOf(node));
brother = leftOf(parentOf(node));
}
//兄弟节点有孩子节点
if (colorOf(leftOf(brother)) == BLACK && colorOf(rightOf(brother)) == BLACK) {
setColor(brother, RED);
node = node.parent;
} else {
if (rightOf(brother) != null && leftOf(brother) == null) {
setColor(brother, RED);
setColor(rightOf(brother), BLACK);
leftRotate(brother);
brother = leftOf(parentOf(node));
}
setColor(brother, colorOf(parentOf(node)));
setColor(leftOf(brother), BLACK);
setColor(parentOf(node), BLACK);
rightRotate(parentOf(node));
node = root;
}
}
}
setColor(node, BLACK);
}
全部代码:
package tree;
import java.util.ArrayList;
import java.util.List;
public class RBTree<K extends Comparable<K>, V> {
private static final boolean RED = false;
private static final boolean BLACK = true;
private Node<K, V> root;
public boolean contains(K key) {
return find(key) != null;
}
private Node find(K key) {
if (key == null) return null;
Node node = root;
while (node != null) {
int compare = key.compareTo((K)node.key);
if(compare == 0) return node;
else if(compare > 0) node = node.right;
else node = node.left;
}
return null;
}
public V remove(K key) {
Node node = getNode(key);
if(node == null) return null;
V oldValue = (V)node.value;
delete(node);
return oldValue;
}
private void delete(Node node) {
if(node == null) return;
//node有两个孩子节点, 找其后继节点替换,并删除后继节点
if(node.left != null && node.right != null) {
// Node sucessor = sucessor(node);
Node sucessor = predecessor(node);
node.key = sucessor.key;
node.value = sucessor.value;
node = sucessor;
}
Node replace = node.left == null? node.right : node.left;
//node没有孩子节点,直接删除
if (replace == null) {
if (node == root) {
root = null;
return;
}
if (node.color == BLACK) {
//要删除黑色叶子节点,需要调整
fixAfterRemove(node);
}
if (node.parent.left == node) node.parent.left = null;
else if (node.parent.right == node) node.parent.right = null;
node.parent = null;
} else {
//node有一个孩子节点,将孩子节点和父节点连接
replace.parent = node.parent;
if (node == root) {
root = replace;
} else if (node.parent.left == node) {
node.parent.left = replace;
} else if (node.parent.right == node) {
node.parent.right = replace;
}
node.right = node.left = node.parent = null;
if (node.color == BLACK) {
//相当于2-3-4树三节点的删除,replace一定是红色,直接染黑
replace.color = BLACK;
}
}
}
private void fixAfterRemove(Node node) {
while (colorOf(node) != RED && node != root) {
//node为左孩子
if (node == leftOf(node.parent)) {
Node brother = rightOf(node.parent);
if (colorOf(brother) == RED) {
setColor(brother, BLACK);
setColor(parentOf(node), RED);
leftRotate(parentOf(node));
brother = rightOf(parentOf(node));
}
//兄弟节点有孩子节点
if (colorOf(leftOf(brother)) == BLACK && colorOf(rightOf(brother)) == BLACK) {
setColor(brother, RED);
node = node.parent;
} else {
if (leftOf(brother) != null && rightOf(brother) == null) {
setColor(brother, RED);
setColor(brother.left, BLACK);
rightRotate(brother);
brother = rightOf(parentOf(node));
}
setColor(brother, colorOf(parentOf(node)));
setColor(rightOf(brother), BLACK);
setColor(parentOf(node), BLACK);
leftRotate(parentOf(node));
node = root;
}
} else {
Node brother = leftOf(node.parent);
if (colorOf(brother) == RED) {
setColor(brother, BLACK);
setColor(parentOf(node), RED);
rightRotate(parentOf(node));
brother = leftOf(parentOf(node));
}
//兄弟节点有孩子节点
if (colorOf(leftOf(brother)) == BLACK && colorOf(rightOf(brother)) == BLACK) {
setColor(brother, RED);
node = node.parent;
} else {
if (rightOf(brother) != null && leftOf(brother) == null) {
setColor(brother, RED);
setColor(rightOf(brother), BLACK);
leftRotate(brother);
brother = leftOf(parentOf(node));
}
setColor(brother, colorOf(parentOf(node)));
setColor(leftOf(brother), BLACK);
setColor(parentOf(node), BLACK);
rightRotate(parentOf(node));
node = root;
}
}
}
setColor(node, BLACK);
}
private Node getNode(K key) {
if (key == null) return null;
Node<K, V> node = root;
while (node != null) {
int compare = key.compareTo(node.key);
if(compare == 0) return node;
else if (compare > 0) {
node = node.right;
} else {
node = node.left;
}
}
return null;
}
/**
* 查找前驱节点
* @param node
* @return
*/
private Node predecessor(Node node) {
if(node == null || node.left == null) return null;
node = node.left;
Node pre = node;
while (node != null) {
pre = node;
node = node.right;
}
return pre;
}
/**
* 查找后继节点
* @param node
* @return
*/
private Node sucessor(Node node) {
if(node == null || node.right == null) return null;
node = node.right;
Node pre = node;
while (node != null) {
pre = node;
node = node.left;
}
return pre;
}
public Node getRoot() {
return root;
}
/**
* 按升序返回搜索二叉树的值
* @return
*/
public List<Entry<K, V>> list() {
List<Entry<K, V>> list = new ArrayList<>();
ldr(root, list);
return list;
}
private void ldr(Node<K, V> node, List<Entry<K, V>> list) {
if (node == null) return;
ldr(node.left, list);
list.add(new Entry<K, V>(node.key, node.value));
ldr(node.right, list);
}
public void put(K key, V value) {
if(root == null) {
root = new Node<K, V>(null, null, null, BLACK, key, value);
return;
}
Node node = root;
Node p = null;
int compare = 0;
while (node != null) {
compare = node.key.compareTo(key);
p = node;
if(compare > 0) {
node = node.left;
} else if(compare < 0) {
node = node.right;
} else {
node.setValue(value);
return;
}
}
Node<K, V> insertNode = new Node(p, null, null, RED, key, value);
if (compare > 0) {
p.left = insertNode;
} else {
p.right = insertNode;
}
//调整
fixAfterPut(insertNode);
}
/**
* 对插入的节点进行调整
* @param node
*/
private void fixAfterPut(Node<K,V> node) {
//node的父节点是爷爷的左孩子
while (node.parent != null && node.parent.color == RED) {
if(parentOf(node) == leftOf(parentOf(parentOf(node)))) {
Node uncle = parentOf(parentOf(node)).right;
if(colorOf(uncle) == RED) {
setColor(parentOf(node), BLACK);
setColor(uncle, BLACK);
node = parentOf(parentOf(node));
if(node != root) {
setColor(node, RED);
}
} else {
if(rightOf(parentOf(node)) == node) {
node = parentOf(node);
leftRotate(node);
}
setColor(parentOf(node), BLACK);
setColor(parentOf(parentOf(node)), RED);
rightRotate(parentOf(parentOf(node)));
}
} else {
//node的父节点是爷爷的右孩子
Node uncle = parentOf(parentOf(node)).left;
if(colorOf(uncle) == RED) {
setColor(parentOf(node), BLACK);
setColor(uncle, BLACK);
node = parentOf(parentOf(node));
if(node != root) {
setColor(node, RED);
}
} else {
if(leftOf(parentOf(node)) == node) {
node = parentOf(node);
rightRotate(node);
}
setColor(parentOf(node), BLACK);
setColor(parentOf(parentOf(node)), RED);
leftRotate(parentOf(parentOf(node)));
}
}
}
}
private void setColor(Node node, boolean color) {
if (node != null) {
node.color = color;
}
}
private boolean colorOf(Node node) {
return node == null? BLACK : node.color;
}
private Node parentOf(Node node) {
return node == null? null : node.parent;
}
private Node leftOf(Node node) {
return node == null? null : node.left;
}
private Node rightOf(Node node) {
return node == null? null : node.right;
}
/**
* 左旋
* @param node
*/
private void leftRotate(Node node) {
if (node != null && node.right != null) {
Node r = node.right;
node.right = r.left;
if(r.left != null) {
r.left.parent = node;
}
r.left = node;
Node parent = node.parent;
r.parent = parent;
node.parent = r;
if(parent == null) {
root = r;
} else if(parent.left == node) {
parent.left = r;
} else {
parent.right = r;
}
}
}
/**
* 右旋
* @param node
*/
private void rightRotate(Node node) {
if (node != null && node.left != null) {
Node l = node.left;
node.left = l.right;
if(l.right != null) {
l.right.parent = node;
}
Node parent = node.parent;
l.right = node;
node.parent = l;
l.parent = parent;
if(parent == null) {
root = l;
} else if(parent.left == node) {
parent.left = l;
} else {
parent.right = l;
}
}
}
static class Entry<K, V> {
private K key;
private V value;
public Entry() {
}
public Entry(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
@Override
public String toString() {
return "Entry{" +
"key=" + key +
", value=" + value +
'}';
}
}
static class Node<K extends Comparable<K>, V> {
private Node parent;
private Node left;
private Node right;
private boolean color;
private K key;
private V value;
public Node getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
public boolean isColor() {
return color;
}
public void setColor(boolean color) {
this.color = color;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
public Node(Node parent, Node left, Node right, boolean color, K key, V value) {
this.parent = parent;
this.left = left;
this.right = right;
this.color = color;
this.key = key;
this.value = value;
}
}
}