亲自动手画红黑树

原文发布于: http://blog.ztgreat.cn/article/12

在前面我们学习了平衡二叉树,伸展树,今天我们来看看另外一种平衡二叉树—红黑树,本来这篇博客早在一年前就该写的,后来发生了太多故事,博客停止了更新了一年,如今又有了最初的斗志,决定好好把博客写下去,对知识的梳理的同时,也不断巩固。
对于各种平衡树,我只能进行简单的理解和实现,无法涉及太多的应用,主要的还是本身自己知识广度和深度有限,不过我相信:不积跬步,无以至千里
本文主要参考了算法导论一书

红黑树本质上就是一棵二叉查找树,一般的二叉查找树比较简单,在以前的博客(点这里)中有提到,不过那个时候写得也比较粗糙,后面会花时间改造一番。

红黑树 它在二叉查找树的基础上增加了着色和相关的性质使得红黑树相对平衡,红黑树有5条性质:
(1)每个节点或者是黑色,或者是红色。
(2)根节点是黑色。
(3)每个叶子节点(null)是黑色。 (注意:这里叶子节点,是指为空(null)的叶子节点
(4)如果一个节点是红色的,则它的子节点必须是黑色的(也就是不能连续的两个红色节点)。
(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。

红黑树中 最短的路径就是全是黑色节点,最长的路径就是红黑相间,由于性质5,因此可以确保没有一条路径会比其他路径长出俩倍。因而,红黑树是相对是接近平衡的二叉树,下面是一颗红黑树的“样子”

红黑树的左旋和右旋

在前面的平衡二叉树中涉及到了旋转操作,这里并不会直接引用原来的图解,重新的说一下旋转操作,因为在平衡二叉树中,主要的操作就是旋转,通过旋转来调整树的结构,因为后面涉及到具体的java代码,这里我们先将节点的定义放出来

    public class RBTNode<T> {
        boolean color;        // 颜色
        T value;               // 节点值
        RBTNode<T> left;      // 左孩子
        RBTNode<T> right;    // 右孩子
        RBTNode<T> parent;    // 父结点
    }
1. 左旋

这里写图片描述
对节点X 进行左旋,也就是:将x变为原位置节点的左节点,也实际是对右子树进行调整,将右子树提升一层,对于Y左子节点b 比X大,比Y小,自然就该放到X的左子树上,整个操作不麻烦

理解了操作方法后,写出伪代码或者具体的代码应该就不难了,下面展示的java代码(代码并不重要,注重思想)

    private void leftRotate(RBTNode<T> x) {
        // 得到x的右孩子y
        RBTNode<T> y = x.right;

        // x的右孩子 为 y的左孩子
        x.right = y.left;

        // 如果 y的左孩子 非空,y的左孩子的父亲 为 x
        if (y.left != null)
            y.left.parent = x;

        // y的父亲 为 x的父亲
        y.parent = x.parent;

        if (x.parent == null) {
            this.Root = y;            // 如果 x的父亲 是空节点,则说明原来的 x 是 根节点,则根节点为y
        } else {
            if (x.parent.left == x)
                x.parent.left = y;    // 如果 x是它父节点的左孩子,则x的父节点的左孩子 为y
            else
                x.parent.right = y;    // 如果 x是它父节点的右孩子,则x的父节点的右孩子 为y
        }

        // y的左孩子 为 x
        y.left = x;
        //x的父节点 为 y
        x.parent = y;
    }
2. 右旋

这里写图片描述
右旋其实和左旋差不多的,只是旋转方向发生了变化。
对节点X 进行右旋,也就是:将节点X变为原节点位置的右节点,也实际是对左子树进行调整,将左子树提示一层,对于Y右子节点b 比X小࿰

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值