当前位置:   article > 正文

基本操作及Java代码实现-红黑树-数据结构和算法_红黑树成员变量有几个

红黑树成员变量有几个
基本操作及Java代码实现-红黑树-数据结构和算法

目录




内容

上面一篇介绍了红黑树的概念、特征和时间复杂度,这里我们进一步讲解红黑树的基础操作和Java代码实现。

数据结构基本操作添加、修改、删除、查询,红黑树做为一种特殊的二叉查找树,其查找和修改同二叉查找树;但是添加、删除和二叉查找树有很大区别。

道理很简单,添加或删除红黑树中的节点之后,红黑树就发生了变化,可能不满足红黑树的5条性质,也就不再是一颗红黑树了,而是一颗普通的树。而通过旋转,可以使这颗树重新成为红黑树。简单点说,旋转的目的是让树保持红黑树的特性。

所有Java代码基本参照HashMap TreeNode完成。

1、红黑树构建

1.1、红黑树的节点分析

红黑树作为一种数据结构,基本功能-存储数据;作为二叉树,有左右子树(节点);具有自己独特的特点,每个节点都有颜色;为了方便查找某个节点的父级节点,用一个指针指向它 的父节点;

  • 红黑树节点Java代码
static final class RBNode<K, V> {
        final K key; // 关键字
        V value; // 数据
        boolean red; // 是否是红色

        private RBNode<K, V> parent; // 父节点指针
        private RBNode<K, V> left; // 左子节点指针
        private RBNode<K, V> right; // 右子节点指针
		
		// 构造函数
        public RBNode(K key, V value, boolean red, RBNode<K, V> parent, RBNode<K, V> left, RBNode<K, V> right) {
            this.key = key;
            this.value = value;
            this.red = red;
            this.parent = parent;
            this.left = left;
            this.right = right;
        }

		/**
		* 以当前节点起始,查找根节点
		*/
        final RBNode<K,V> root() {
            for (RBNode<K,V> r = this, p;;) {
                if ((p = r.parent) == null)
                    return r;
                r = p;
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

1.2、 红黑树成员变量

要查看红黑树,需要有一个切入点,就是红黑树的根节点;想要指定存储了几个元素,需要size变量。

1.3、红黑树的基本操作

  • 左旋
  • 右旋
  • 插入
  • 插入后平衡跳转
  • 删除
  • 删除后平衡跳转
  • 判断是否为空
  • 获取元素个数
  • 打印
  • 查找(根据节点key)

1.4、红黑树类代码

完整代码在最后仓库地址。

2.变色

因为上面我设计用布尔值存储节点的颜色信息,这个很容易实现,通过设置true,节点为红色;false,节点为黑色。
图示:
在这里插入图片描述

3、左旋

  • 旋转过程图示:在这里插入图片描述

  • 步骤

  1. 对目标节点p向左旋转(逆时针)
  2. p节点右节点r的左节点rl 成为 p的右节点,如果rl不为空,rl的父节点变为p节点
  3. p的父节点pp变为r的父节点,如果pp为空,则说明原p为根节点,现在根节点root指向r
  4. 如果p为pp的左节点,则pp的左节点设置为r;否则pp的右节点设置为r。
  5. p的父节点变为r,r的左节点变为p
  • 代码实现
 // 左旋
    static <K, V> RBNode<K, V> rotateLeft(RBNode<K, V> root, RBNode<K, V> p) {
        RBNode<K, V> r, pp, rl;
        if (p != null && (r = p.right) != null) {
            if ((rl = p.right = r.left) != null)
                rl.parent = p;
            if ((pp = r.parent = p.parent) == null)
                (root = r).red = false;
            else if (pp.left == p)
                pp.left = r;
            else
                pp.right = r;
            r.left = p;
            p.parent = r;

        }
        return root;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

3、右旋

  • 旋转过程图示:在这里插入图片描述

  • 步骤

  1. 对目标节点p向右旋转(顺时针)
  2. p节点左节点l的右节点lr 成为 p的左节点,如果lr不为空,lr的父节点变为p节点
  3. p的父节点pp变为l的父节点,如果pp为空,则说明原p为根节点,现在根节点root指向l
  4. 如果p为pp的左节点,则pp的左节点设置为l;否则pp的右节点设置为l。
  5. p的父节点变为pl,pl的左节点变为p
  • 代码实现
 // 右旋
    static <K, V> RBNode<K, V> rotateRight(RBNode<K, V> root, RBNode<K, V> p) {
        RBNode<K, V> l, pp, lr;
        if (p != null && (l = p.left) != null) {
            if ((lr = p.left = l.right) != null)
                lr.parent = p;
            if ((pp = l.parent = p.parent) == null)
                (root = l).red = false;
            else if (pp.left == p)
                pp.left = l;
            else pp.right = l;
            l.right = p;
            p.parent = l;

        }
        return root;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

后记

  欢迎交流,本人QQ:806797785

项目源代码地址:https://gitee.com/gaogzhen/algorithm.git
  • 1
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/746976
推荐阅读
相关标签
  

闽ICP备14008679号