红黑树--基本概念&&左旋转和右旋转--Java实现

一.基本概念

  首先,红黑树是二叉搜索树,但不一定是平衡树。

  红黑树的五条性质:

1.每个结点非红即黑,必定有颜色。

2.根结点是黑的,值为null的节点也是黑的。

3.每个叶子结点都是黑的。

4.如果一个结点是红的,那么它的两个儿子都是黑的。

5.对于任意结点而言,其到叶结点树尾端的每条路径都包含相同数目的黑结点。

  其次,红黑树在Java中的应用也有具现。

  TreeMap,HashMap(哈希冲突多于8个底层就从链表转为红黑树了)底层都用到了红黑树。

  刚接触红黑树的时候我也在想,都有了AVL树这么优秀的平衡树了,红黑树存在的意义是什么呢?

  在查阅了相关资料后我发现:

   1.删除的时候AVL树为了节点平衡,复原树的时候开销大;

     删除节点导致失衡,AVL树需要维护从被删除节点到根节点root这条路径上所有节点的平衡,旋转的量级为O(logN),而红黑树最多只需要旋转3次实现复衡,只需O(1),所以说红黑树删除节点后的复原树的效率更高,开销更小!

   2.插入节点导致树失衡的情况,AVL树和红黑树都是最多两次树旋转来实现复原树操作,旋转的量级都是O(1)

   3.由于AVL树高度平衡,因此AVL树的查询效率更高

   4.在百万级的情况下,红黑树并没有AVL树效率高多少。

   5.在千万级或上亿级的情况下,红黑树才体现出比AVL树效率高。

二.红黑树的左旋转和右旋转

1.红黑树的左旋转:

   先上一下节点类型的定义:

 /**
     * 节点类型定义
     *
     * @param <T>
     */
    private static class Entry<T extends Comparable<T>> {
        T data;
        Entry<T> left;
        Entry<T> right;
        Entry<T> parent;
        Color color;

        public Entry(T data, Entry<T> left, Entry<T> right, Entry<T> parent, Color color) {
            this.data = data;
            this.left = left;
            this.right = right;
            this.parent = parent;
            this.color = color;
        }

    }


 /**
     * 指向红黑树的根节点
     */
    private Entry<T> root;

    public RBTree() {
        this.root = null;
    }

然后图解一下红黑树的左旋转操作:

红黑树左旋转的代码:

    /**
     * 节点的左旋转操作
     *
     * @param node
     */
    private void leftRotate(Entry<T> node) {
        Entry<T> child = node.right;
        child.parent = node.parent;
        //判断node节点是否为根节点,如果是,那么child将成为根节点
        if (null == node.parent) {
            this.root = child;
        } else {
            //判断node节点是它父亲节点的左孩子还是右孩子,再进行移动
            if (node.parent.left == node) {
                node.parent.left = child;
            } else {
                node.parent.right = child;
            }
        }//以上为图中的  1  操作


        node.right = child.left;
        if (null != child.left) {
            child.left.parent = node;
        }
        //以上为图中的   2  操作

        child.left = node;
        node.parent = child;
        //以上为图中的   3  操作
    }

2.红黑树的右旋转

和左旋转道理一样,就是旋转方向不同。

代码:

/**
     * 节点的右旋转操作
     *
     * @param node
     */
    private void rightRotate(Entry<T> node) {
        Entry<T> child = node.left;
        child.parent = node.parent;
        if (null == node.parent) {
            this.root = child;
        } else {
            if (node.parent.left == node) {
                node.parent.left = child;
            } else {
                node.parent.right = child;
            }
        }

        node.left = child.right;
        if (null != child.right) {
            child.right.parent = node;
        }

        child.right = node;
        node.parent = child;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值