java 红黑树之旋转和重新着色的实现

在Java中实现红黑树的旋转和重新着色操作是红黑树维护平衡的关键部分。红黑树通过左旋(left rotate)、右旋(right rotate)以及重新着色(recoloring)等操作来保持树的平衡性。下面我将简要介绍这些操作的基本思想,并提供Java代码示例。

1. 旋转操作

左旋(Left Rotate)

左旋是将一个节点以其右孩子为轴进行顺时针旋转的操作。旋转后,原右孩子成为新的根节点,原节点成为新根节点的左孩子,原右孩子的左孩子(如果有)成为原节点的右孩子。

private void leftRotate(RedBlackTreeNode<T> x) {  
    RedBlackTreeNode<T> y = x.right;  
    x.right = y.left;  
    if (y.left != null) {  
        y.left.parent = x;  
    }  
    y.parent = x.parent;  
    if (x.parent == null) {  
        this.root = y;  
    } else if (x == x.parent.left) {  
        x.parent.left = y;  
    } else {  
        x.parent.right = y;  
    }  
    y.left = x;  
    x.parent = y;  
}

右旋(Right Rotate)

右旋是将一个节点以其左孩子为轴进行逆时针旋转的操作。旋转后,原左孩子成为新的根节点,原节点成为新根节点的右孩子,原左孩子的右孩子(如果有)成为原节点的左孩子。

private void rightRotate(RedBlackTreeNode<T> x) {  
    RedBlackTreeNode<T> y = x.left;  
    x.left = y.right;  
    if (y.right != null) {  
        y.right.parent = x;  
    }  
    y.parent = x.parent;  
    if (x.parent == null) {  
        this.root = y;  
    } else if (x == x.parent.right) {  
        x.parent.right = y;  
    } else {  
        x.parent.left = y;  
    }  
    y.right = x;  
    x.parent = y;  
}

2. 重新着色

重新着色主要是将节点的颜色从红色改为黑色,或从黑色改为红色,以维持红黑树的性质。这通常与旋转操作一起使用,以确保在插入或删除节点后,树仍然保持平衡。

示例:插入节点后的修复
当在红黑树中插入一个新节点时,该节点被着色为红色。如果这违反了红黑树的性质,则需要进行一系列的旋转和重新着色操作来恢复平衡。

private void fixAfterInsertion(RedBlackTreeNode<T> z) {  
    RedBlackTreeNode<T> y;  
    while (z != root && z.parent.color == Color.RED) {  
        if (z.parent == z.parent.parent.left) {  
            y = z.parent.parent.right;  
            if (y != null && y.color == Color.RED) {  
                // Case 1: z的叔父节点y也是红色的  
                z.parent.color = Color.BLACK;  
                y.color = Color.BLACK;  
                z.parent.parent.color = Color.RED;  
                z = z.parent.parent;  
            } else {  
                if (z == z.parent.right) {  
                    // Case 2: z是右孩子  
                    z = z.parent;  
                     leftRotate(z);  
                }  
                // Case 3: z是左孩子,且z的叔父节点是黑色的  
                z.parent.color = Color.BLACK;  
                z.parent.parent.color = Color.RED;  
                rightRotate(z.parent.parent);  
            }  
        } else {  
            // 与上面类似,但处理的是z是左孩子的情况  
            // ...(省略,与右子树情况镜像)  
        }  
    }  
    root.color = Color.BLACK;  
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cesske

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值