public class RBTreeTest {
private static enum Color{
RED,
BLACK
}
private static class Node {
Integer data ;
Node parent;
Node left;
Node right;
Color color;
public Node(int data,Node parent){
this.data = data;
this.parent = parent;
this.color = Color.RED;
}
@Override
public String toString() {
return "[color = "+color +" , data = "+data+"]";
}
}
private static void setRootBlack(Node node) {
node.color = Color.BLACK;
root = node;
}
private static Node root = null;
public static void main(String[] args) {
int[] arr = {12 ,1 ,9 ,2 ,0 ,11, 7, 19 ,4 ,15 ,18 ,5 ,14, 13 ,10 ,16, 6 ,3 ,8 ,17};
for(int i : arr)
insert(i);
System.out.println(root);
}
private static void insert(int data){
/**
* 1、 找到对应的insert位置
* 2、 旋转 着色
*/
Node node = findInsertIndex(root , data);
/**
* case 1 : 父节点为空,当前节点是root涂成黑色
* case 2 : 父节点是黑色,不需要做处理
* case 3 : 父节点和叔叔都是红色,先将父节点和叔叔涂成黑色
* 然后将爷爷涂成红色,然后递归调用爷爷节点的fixupNode(g)
* case 4 : 父节点是红色,叔叔是黑色,并且 当前节点与父节点的左右属性相反
* (例:父节点是爷爷的左节点 , 当前节点是父节点的右节点)
* 先左或右旋(注意调用旋转函数传递参数应该是父节点)
* 完成之后再递归调用fixupNode(p) 必然会执行case 5
* case 5 : 父节点是红色,叔叔是黑色,并且当前节点与父节点的左右属性一致
* 将父节点和爷爷节点都变色 ,然后旋转 rotate(g)
*/
fixupNode(node);
}
/**
* p : 父节点
* g : 爷爷节点
* u : 叔叔节点
* l : 左子节点
* r : 右子节点
*/
private static void fixupNode(Node node) {
Node p = node.parent;
if(p == null)
setRootBlack(node); //case 1
else{
if(p.color == Color.BLACK)
return ; //case 2
else{
Node g = p.parent;
Node u = findUncle(node);
if(u != null && u.color == Color.RED){
//case 3
p.color = Color.BLACK;
u.color = Color.BLACK;
g.color = Color.RED;
fixupNode(g);
}else{
if(isLeft(p)){
if(isLeft(node)){
//case 5
p.color = Color.BLACK;
g.color = Color.RED;
rotateRight(g);
}else{
//case 4
rotateLeft(p);
fixupNode(p);
}
}else{
if(isLeft(node)){
//case 4
rotateRight(p);
fixupNode(p);
}else{
//case 5
p.color = Color.BLACK;
g.color = Color.RED;
rotateLeft(g);
}
}
}
}
}
}
private static void rotateLeft(Node n) {
Node r = n.right;
Node p = n.parent;
Node t = r.left;
if(p != null){
if(isLeft(n))
p.left = r;
else
p.right = r;
}
r.parent = p;
r.left = n;
n.parent = r;
n.right = t;
if(t != null)
t.parent = n;
if(p == null)
root = n.parent;
}
private static void rotateRight(Node n){
Node l = n.left;
Node p = n.parent;
Node t = l.right;
if(p != null){
if(isLeft(n))
p.left = l;
else
p.right = l;
}
l.parent = p;
l.right = n;
n.parent = l;
n.left = t;
if(t != null)
t.parent = n;
if(p == null)
root = n.parent;
}
private static boolean isLeft(Node g) {
return g.parent == null || g == g.parent.left;
}
private static Node findUncle(Node node) {
Node g = node.parent.parent;
if(node.parent == g.left)
return g.right;
else
return g.left;
}
private static Node findInsertIndex(Node node , int data) {
if(node == null)
return root = new Node(data,null);
if(node.data > data){
if(node.left == null)
return node.left = new Node(data,node);
return findInsertIndex(node.left,data);
}else if(node.data < data){
if(node.right == null)
return node.right = new Node(data,node);
return findInsertIndex(node.right,data);
}else
return node;
}
}
红黑树算法
最新推荐文章于 2025-04-12 15:13:50 发布