Java红黑树中左旋和右旋的实现

红黑树

R-B Tree,全称是Red-Black Tree,又称为“红黑树”,它一种特殊的二叉查找树。红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black)。

红黑树的特性:
1)每个节点或者是黑色,或者是红色。
2)根节点是黑色。
3)每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NILNULL)的叶子节点!]
4)如果一个节点是红色的,则它的子节点必须是黑色的。
5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。

注意
(01) 特性(3)中的叶子节点,是只为空(NILnull)的节点。
(02) 特性(5),确保没有一条路径会比其他路径长出俩倍。因而,红黑树是相对是接近平衡的二叉树。

应用

红黑树的应用比较广泛,主要是用它来存储有序的数据,它的时间复杂度是O(lgn),效率非常之高。
例如,Java集合中的TreeSetTreeMapLinux虚拟内存的管理,都是通过红黑树去实现的

左旋和右旋

         红黑树的基本操作是添加、删除和旋转。在对红黑树进行添加或删除后,会用到旋转方法。为什么呢?道理很简单,添加或删除红黑树中的节点之后,红黑树就发生了变化,可能不满足红黑树的5条性质,也就不再是一颗红黑树了,而是一颗普通的树。而通过旋转,可以使这颗树重新成为红黑树。简单点说,旋转的目的是让树保持红黑树的特性。

代码如下

package com.example.demo.RedBlankTree;

/**
 * 红黑树
 *
 * 左旋和右旋实现
 * @author hh
 */
public class RBTree {

    RBNode root;

    /**
     * 对x进行左旋
     * 从上往下看变化
     *       p                            p
     *      /                            /
     *     x            对x左旋          y
     *    / \         ------->         /\
     *   lx  y                        x  ry
     *      /\                       / \  
     *    ly ry                     lx ly  
     *
     * @param x
     */
    private void leftRoute(RBNode x) {
        RBNode y = x.right;
        RBNode ly = y.left;
        //将y的左节点指向x的右节点
        x.right = ly;
        //如果y的左节点ly不为空 把ly的父节点 指向x
        if (ly != null) {
            ly.parent = x;
        }
        //将原来x的父节点 指向为y的父节点(更新父节点)
        y.parent = x.parent;
        if (x.parent == null) {
            this.root = y;
        } else {
            //如果x为左节点
            if (x == x.parent.left) {
                x.parent.left = y;
            } else {
                //如果x为右节点
                x.parent.right = y;
            }
        }
        //更新xy与下面子节点的关系
        y.left = x;
        x.parent = y;
    }

    /**
     * 右旋
     * 同上
     *
     * @param x
     */
    private void rightRoute(RBNode x) {
        RBNode y = x.left;
        x.left = y.right;
        if (y.right != null) {
            y.right.parent = x;
        }
        if (y == null) {
            this.root = y;
        } else {
            if (x == x.parent.left) {
                //如果为左节点
                x.parent.left = y;
            } else {
                //x为右节点
                x.parent.right = y;
            }
        }
        y.left = x;
        x.parent = y;
    }

    /**
     * 红黑树节点
     *
     * @param <T>
     */
    final class RBNode<T extends Comparable<T>> {
        /**
         * 颜色
         */
        boolean color;
        /**
         * 节点值
         */
        T key;
        /**
         * 左节点
         */
        RBNode<T> left;
        /**
         * 右节点
         */
        RBNode<T> right;
        /**
         * 父节点
         */
        RBNode<T> parent;

        public T getKey() {
            return key;
        }
    }
}

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值