仿照TreeMap的源码实现了红黑树的插入操作:
public class RBTreeTest<T> {
private transient Node<T> root;
private static final boolean RED = false;
private static final boolean BLACK = true;
private static boolean valEquals(Object data, Object o) {
return data == null ? o == null : data.equals(o);
}
@Data
static final class Node<T> {
private T data;
private Node<T> left;
private Node<T> right;
private Node<T> parent;
boolean color = BLACK;
Node(T data, Node<T> parent) {
this.data = data;
this.parent = parent;
}
public T setValue(T data) {
T oldData = this.data;
this.data = data;
return oldData;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Node<?> node = (Node<?>) o;
return valEquals(data, node.getData());
}
@Override
public int hashCode() {
return data == null ? 0 : data.hashCode();
}
@Override
public String toString() {
return data + "";
}
}
...
}
左旋
1、X—Y.left X.parent—Y.parent X—Y 旋转主要是这三者之间的关系调整
private void rotateLeft(Node<T> node) {
if(node != null) {
Node<T> p = node.right;
node.right = p.left;
if(p.left != null)
p.left.parent = node;
p.parent = node.parent;
if(node.parent == null)
root = p;
else if(node.parent.left == node)
node.parent.left = p;
else
node.parent.right = p;
p.left = node;
node.parent = p;
}
}
右旋
1、X—Y.right X.parent—Y.parent X—Y 旋转主要是这三者之间的关系调整
private void rotateRight(Node<T> node) {
if(node != null) {
Node<T> p = node.left;
node.left = p.right;
if(p.right != null)
p.right.parent = node;
p.parent = node.parent;
if(node.parent == null)
root = p;
else if (node.parent.right == node)
node.parent.right = p;
else
node.parent.left = p;
p.right = node;
node.parent = p;
}
}
插入节点
public T put(T data) {
Node<T> p = root;
Node<T> parent;
int compare;
@SuppressWarnings("unchecked")
Comparable<? super T> data1 = (Comparable<? super T>) data;
do {
parent = p;
// 比较data与当前节点数据大小关系
compare = data1.compareTo(p.data);
if (compare < 0) {
p = p.left;
} else if (compare > 0) {
p = p.right;
} else {
return p.setValue(data);
}
} while (p != null);
Node<T> k = new Node<>(data, parent);
if (compare < 0) {
parent.left = k;
} else {
parent.right = k;
}
// 节点插入之后,进行红黑树的平衡调整
fixAfterInsertion(k);
return null;
}
插入后调整
private void fixAfterInsertion(Node<T> node) {
// 根据红黑树特性,新插入节点设置为红色
node.color = RED;
while (node != null && node != root && node.parent.color == RED) {
if(parentOf(node) == leftOf(parentOf(parentOf(node)))) {
Node<T> uncle = rightOf(parentOf(parentOf(node)));
if(colorOf(uncle) == RED) {
setColor(parentOf(node), BLACK);
setColor(uncle, BLACK);
setColor(parentOf(parentOf(node)), RED);
node = parentOf(parentOf(node));
} else {
if(node == rightOf(parentOf(node))) {
node = parentOf(node);
rotateLeft(node);
}
setColor(parentOf(node), BLACK);
setColor(parentOf(parentOf(node)), RED);
rotateRight(parentOf(parentOf(node)));
}
} else {
Node<T> leftUncle = leftOf(parentOf(parentOf(node)));
if(colorOf(leftUncle) == RED) {
setColor(parentOf(node), BLACK);
setColor(leftUncle, BLACK);
setColor(parentOf(parentOf(node)), RED);
node = parentOf(parentOf(node));
} else {
if(node == leftOf(parentOf(node))) {
node = parentOf(node);
rotateRight(node);
}
setColor(parentOf(node), BLACK);
setColor(parentOf(parentOf(node)), RED);
rotateLeft(parentOf(parentOf(node)));
}
}
}
root.color = BLACK;
}