如何在Java中实现一个红黑树?
时间: 2024-03-09 17:45:33 浏览: 50
在Java中实现一个红黑树可以通过以下步骤:
1. 定义红黑树的节点结构,包括节点的值、颜色、父节点、左子节点和右子节点等属性。
```java
enum Color {
RED,
BLACK
}
class Node {
int val;
Color color;
Node parent;
Node left;
Node right;
public Node(int val) {
this.val = val;
this.color = Color.RED; // 新插入的节点默认为红色
}
}
```
2. 实现红黑树的插入操作,它要求按照红黑树的规则将新节点插入到正确的位置上,并通过旋转和变色操作来保持树的平衡。
```java
class RedBlackTree {
Node root;
public void insert(int val) {
Node node = new Node(val);
Node parent = null;
Node current = root;
// 查找新节点的插入位置
while (current != null) {
parent = current;
if (val < current.val) {
current = current.left;
} else {
current = current.right;
}
}
// 将新节点插入到树中
node.parent = parent;
if (parent == null) {
root = node;
} else if (val < parent.val) {
parent.left = node;
} else {
parent.right = node;
}
// 调整树的平衡
insertFixup(node);
}
private void insertFixup(Node node) {
while (node.parent != null && node.parent.color == Color.RED) {
// 父节点是祖父节点的左子节点
if (node.parent == node.parent.parent.left) {
Node uncle = node.parent.parent.right;
if (uncle != null && uncle.color == Color.RED) {
// Case 1:叔叔节点是红色
node.parent.color = Color.BLACK;
uncle.color = Color.BLACK;
node.parent.parent.color = Color.RED;
node = node.parent.parent;
} else {
// Case 2:叔叔节点是黑色,且当前节点是右子节点
if (node == node.parent.right) {
node = node.parent;
leftRotate(node);
}
// Case 3:叔叔节点是黑色,且当前节点是左子节点
node.parent.color = Color.BLACK;
node.parent.parent.color = Color.RED;
rightRotate(node.parent.parent);
}
} else {
// 父节点是祖父节点的右子节点
Node uncle = node.parent.parent.left;
if (uncle != null && uncle.color == Color.RED) {
// Case 1:叔叔节点是红色
node.parent.color = Color.BLACK;
uncle.color = Color.BLACK;
node.parent.parent.color = Color.RED;
node = node.parent.parent;
} else {
// Case 2:叔叔节点是黑色,且当前节点是左子节点
if (node == node.parent.left) {
node = node.parent;
rightRotate(node);
}
// Case 3:叔叔节点是黑色,且当前节点是右子节点
node.parent.color = Color.BLACK;
node.parent.parent.color = Color.RED;
leftRotate(node.parent.parent);
}
}
}
root.color = Color.BLACK;
}
private void leftRotate(Node node) {
Node right = node.right;
node.right = right.left;
if (right.left != null) {
right.left.parent = node;
}
right.parent = node.parent;
if (node.parent == null) {
root = right;
} else if (node == node.parent.left) {
node.parent.left = right;
} else {
node.parent.right = right;
}
right.left = node;
node.parent = right;
}
private void rightRotate(Node node) {
Node left = node.left;
node.left = left.right;
if (left.right != null) {
left.right.parent = node;
}
left.parent = node.parent;
if (node.parent == null) {
root = left;
} else if (node == node.parent.left) {
node.parent.left = left;
} else {
node.parent.right = left;
}
left.right = node;
node.parent = left;
}
}
```
3. 实现红黑树的删除操作,它要求按照红黑树的规则删除指定的节点,并通过旋转和变色操作来保持树的平衡。
```java
class RedBlackTree {
...
public void delete(int val) {
Node node = search(val);
if (node == null) {
return;
}
Node replace = null;
Color originalColor = node.color;
if (node.left == null) {
replace = node.right;
transplant(node, node.right);
} else if (node.right == null) {
replace = node.left;
transplant(node, node.left);
} else {
Node min = minimum(node.right);
replace = min.right;
originalColor = min.color;
if (min.parent == node) {
replace.parent = min;
} else {
transplant(min, min.right);
min.right = node.right;
min.right.parent = min;
}
transplant(node, min);
min.left = node.left;
min.left.parent = min;
min.color = node.color;
}
if (originalColor == Color.BLACK) {
deleteFixup(replace);
}
}
private void deleteFixup(Node node) {
while (node != root && node.color == Color.BLACK) {
if (node == node.parent.left) {
Node sibling = node.parent.right;
if (sibling.color == Color.RED) {
// Case 1:兄弟节点是红色
sibling.color = Color.BLACK;
node.parent.color = Color.RED;
leftRotate(node.parent);
sibling = node.parent.right;
}
if (sibling.left.color == Color.BLACK && sibling.right.color == Color.BLACK) {
// Case 2:兄弟节点和它的子节点都是黑色
sibling.color = Color.RED;
node = node.parent;
} else {
if (sibling.right.color == Color.BLACK) {
// Case 3:兄弟节点是黑色,兄弟节点的左子节点是红色,右子节点是黑色
sibling.left.color = Color.BLACK;
sibling.color = Color.RED;
rightRotate(sibling);
sibling = node.parent.right;
}
// Case 4:兄弟节点是黑色,兄弟节点的右子节点是红色
sibling.color = node.parent.color;
node.parent.color = Color.BLACK;
sibling.right.color = Color.BLACK;
leftRotate(node.parent);
node = root;
}
} else {
Node sibling = node.parent.left;
if (sibling.color == Color.RED) {
// Case 1:兄弟节点是红色
sibling.color = Color.BLACK;
node.parent.color = Color.RED;
rightRotate(node.parent);
sibling = node.parent.left;
}
if (sibling.right.color == Color.BLACK && sibling.left.color == Color.BLACK) {
// Case 2:兄弟节点和它的子节点都是黑色
sibling.color = Color.RED;
node = node.parent;
} else {
if (sibling.left.color == Color.BLACK) {
// Case 3:兄弟节点是黑色,兄弟节点的右子节点是红色,左子
阅读全文