Android版数据结构与算法(十):终极之树-红黑树与TreeMap详细解析

2023-10-29

本文目录

一、为什么要创建红黑树这种数据结构

在上篇我们了解了AVL树,既然已经有了AVL这种平衡的二叉排序树,为什么还要有红黑树呢?

AVL树通过定义我们知道要求树中每一个结点的左右子树高度差的绝对值不超过1,其是一颗严格的平衡树,这样构建出来的平衡二叉排序树具有很好的查找性能,但是为了保持其每个结点平衡因子绝对值不超过1的特性在插入或者删除的时候需要的维护成本是很大的,插入或者删除需要大量的平衡度计算,比如上一篇在AVL的插入的时候就需要不断回溯其父节点调整平衡因子的值,数据量小没什么问题,但是实际应用中往往数据量是很大的,导致AVL树的插入删除维护成本会很高。

此时,就有一部分前人们思考可不可以发明一种数据结构查找性能和AVL树差不多,但是插入删除的时候不需要那么大的维护开销呢?

1972年,鲁道夫·贝尔老爷子就发明了这样一种数据结构: 平衡二叉B树,后来在1978年的时候经过修改才叫红黑树

以上了解了AVL树的问题以及红黑树的发明创造,下面正式讲解红黑树。

二、红黑树定义

直接给出:

1.节点是红色或黑色。
2.根节点是黑色。
3.每个叶子节点都是黑色的空节点(NIL节点)。
4.每个红色节点的两个子节点都是黑色(从每个叶子到根的所有路径上不能有两个连续的红色节点)。
5.从任一节点到其每个叶子结点的所有路径都包含相同数目的黑色节点。

这里的叶子结点指的是NIL结点,而不是我们平时所指的叶子结点。

满足以上条件的二叉排序树就是一颗红黑树,AVL树与红黑树前提都是二叉排序树。

以下就是一颗红黑树:

这里标记出了NIL结点,之后就不在标记出了,忽略不计了

以上定义就保证了红黑树不需要像AVL树一样保证左右子树高度差绝对值不超过1,但是也保证了红黑树左右子树高度差不会相差2倍以上,怎么理解呢?怎么就保证不相差两倍以上呢?

三、红黑树如何保证左右子树高度差不会相差很大的

先跟着我的思路进行下面操作

比如以上面举例的红黑树为例,我们在根结点的右子树再插入结点,那么这个结点的颜色只能是红色,因为如果插入的是黑色,那么违反红黑树中第5条约束,如图:

如图,如果在根结点右子树再插入黑色结点那么左侧8到7有两个给色结点,而右侧8到11则有3个黑色结点,显然违反第5条约束。

所以我们只能插入红色结点:

在上图基础上我们在继续想右子树插入结点,根据约束4:红色结点的孩子只能是黑结点,然而插入黑色结点又违反约束5,这里就形成了死循环,无法继续下去。

所以极端情况下,对于上述一棵树,在不进行平衡操作的前提下,根结点左右子树高度差最大为2,。

这里只是举了一个例子说明红黑树红黑树是如何保证左右子树高度差不相差很大的,上面说的都是在不进行平衡操作的前提下,真正的红黑树结点是随便插入的,在违反上述约束会进行相应调整。

四、红黑树添加结点

讲解红黑树的添加算法之前我们先看看TreeMap添加数据的逻辑。

TreeMap与HashMap比较最大特点就是其是有序的Map集合,并且其底层数据结构为红黑树,我们先来简单了解下TreeMap的存储结构。

TreeMap每个存储结构为TreeMapEntry类,源码如下:

    static final class TreeMapEntry<K,V> implements Map.Entry<K,V> {
        K key;
        V value;
        TreeMapEntry<K,V> left;
        TreeMapEntry<K,V> right;
        TreeMapEntry<K,V> parent;
        boolean color = BLACK;

        /**
         * Make a new cell with given key, value, and parent, and with
         * {@code null} child links, and BLACK color.
         */
        TreeMapEntry(K key, V value, TreeMapEntry<K,V> parent) {
            this.key = key;
            this.value = value;
            this.parent = parent;
        }

        /**
         * Returns the key.
         *
         * @return the key
         */
        public K getKey() {
            return key;
        }

        /**
         * Returns the value associated with the key.
         *
         * @return the value associated with the key
         */
        public V getValue() {
            return value;
        }

        /**
         * Replaces the value currently associated with the key with the given
         * value.
         *
         * @return the value associated with the key before this method was
         *         called
         */
        public V setValue(V value) {
            V oldValue = this.value;
            this.value = value;
            return oldValue;
        }

        public boolean equals(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry<?,?> e = (Map.Entry<?,?>)o;

            return valEquals(key,e.getKey()) && valEquals(value,e.getValue());
        }

        public int hashCode() {
            int keyHash = (key==null ? 0 : key.hashCode());
            int valueHash = (
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android版数据结构与算法(十):终极之树-红黑树与TreeMap详细解析 的相关文章

随机推荐

  • 信捷总线Xnet-速度模式使用总结

    XDC类型的PLC的串口配置 主要是串口1与串口4 串口1 X Net RS232 32768 2 OMMS 57600 串口4 X Net RS485 32768 2 OMMS 3000000 周期通讯 PLC配置 N为站号 可参考Xne
  • Neo4j 环境配置及问题解决

    问题目录 1 环境配置 Jdk环境配置 Neo4j下载地址 环境变量 2 遇到的问题 jdk版本不匹配 在配置neo4j install service时失败 1 环境配置 Jdk环境配置 jdk配置这里就不说啦 Neo4j下载地址 官网下
  • Rxjs的flatMap使用

    Rxjs的flatMap使用 flatMap是Rxjs比较绕的一个概念 这里我们只是讲解如何使用 在Rxjs 4 0版本时叫flatMap 在Rxjs 5 0时被更名为margeMap 现在flatMap作为margeMap的别名使用 这是
  • 3D车道线单目检测方法ONCE-3DLanes

    3D车道线检测论文 ONCE 3DLanes Building Monocular 3D Lane Detection 上传arXiv于2022年5月 是华为诺亚和复旦大学的工作 由于道路不平 传统的单目图像2D车道线检测在自动驾驶的跟踪规
  • Linux系统Load average负载详细解释

    我们知道判断一个系统的负载可以使用top uptime等命令去查看 它分别记录了一分钟 五分钟 以及十五分钟的系统平均负载 例如我的某台 服务器 root ccidcom uptime 13 14 32 up 79 days 4 00 1
  • 数组——筛选数组

    将数组 2 0 6 1 77 0 52 0 25 7 中大于等于10的元素选出来 放入新数组 实现分析 1 声明一个新的空数组 用来存放 gt 10 的元素 2 for循环遍历数组中的每个元素 判断是否大于等于10 将其存到声明的空数组中
  • python从tushare获取股票历史数据

    使用前提 安装Python 安装pandas lxml也是必须的 正常情况下安装了Anaconda后无须单独安装 如果没有可执行 pip install lxml 建议安装Anaconda 一次安装包括了Python环境和全部依赖包 减少问
  • 指定springboot的jar运行内存

    一般情况下 我们运行一个springboot的jar包 是这样运行的 java jar xxx jar 如果想指定运行的内存 可以这样 java Xms10m Xmx200m jar xxx jar 这个参数是java命令的参数 其他详细的
  • 中断产生EINTR错误

    https blog csdn net u011068702 article details 62069714 1 介绍慢系统调用 该术语适用于那些可能永远阻塞的系统调用 永远阻塞的系统调用是指调用永远无法返回 多数网络支持函数都属于这一类
  • C语言一维数组练习例题及答案

    1 运动场上 一群学生正绕操场跑步 看台上一个小朋友专注地看着 他想找出他们中身高最高的人排在第几位 请编写程序模拟找出最大值的排位 要求先往数组中输入10个元素 再输出数组中最大值的下标 例如 输入 1 2 3 4 5 6 7 8 9 1
  • 基于SpringBoot前后端分离的网吧管理系统

    末尾获取源码 开发语言 Java Java开发工具 JDK1 8 后端框架 SpringBoot 前端 采用Vue技术开发 数据库 MySQL5 7和Navicat管理工具结合 服务器 Tomcat8 5 开发软件 IDEA Eclipse
  • Linux之命令查看器

    命令查看器 https wangchujiang com linux command c iptables html
  • html中input禁用缓存 使用标签 关闭 input 缓存

    实现1 在单个input 中 禁用缓存 autocomplete off 默认no
  • base -2 Number——进制转换

    题目描述 Given an integer N find the base 2 representation of N Here S is the base 2 representation of N when the following
  • Activity的6大难点,你会几个?建议收藏

    近日一好友去阿里面试 面试失败了 分享了一个他最不擅长的算法面试题 题目是这样的 题目 给定一个二叉搜索树 BST 找到树中第 K 小的节点 出题人 阿里巴巴出题专家 文景 阿里云 CDN 资深技术专家 参考答案 考察点 基础数据结构的理解
  • C和C++安全编码笔记:整数安全

    5 1 整数安全导论 整数由包括0的自然数 0 1 2 3 和非零自然数的负数 1 2 3 构成 5 2 整数数据类型 整数类型提供了整数数学集合的一个有限子集的模型 一个具有整数类型的对象的值是附着在这个对象上的数学值 一个具有整数类型的
  • 1016:整型数据类型存储空间大小(C C++)

    题目描述 分别定义int short类型的变量各一个 并依次输出它们的存储空间大小 单位 字节 输入 无 输出 一行 两个整数 分别是两个变量的存储空间大小 用一个空格隔开 输入样例 无 输出样例 无 代码 include
  • Qt学习(五)—— QWidget对象模型

    在Qt中 所有窗口及窗口控件都是从QWidget直接或间接派生出来的 对象模型 在Qt中创建对象的时候会提供一个Parent对象指针 下面来解释这个parent到底是干什么的 QObject是以对象树的形式组织起来的 当你创建一个QObje
  • 塔湖智能获数百万元种子轮投资,打造AI出海营销机器人

    据悉 专注于全球出海AI营销机器人服务商 塔湖智能获得由民峰资本领投及个人企业家跟投的数百万种子轮融资 民峰资本投资负责人Ethan Wei表示 塔湖智能团队拥有丰富的出海经验以及营销领域的海外本土化执行力 希望塔湖智能拥抱AGI赛道 研发
  • Android版数据结构与算法(十):终极之树-红黑树与TreeMap详细解析

    本文目录 一 为什么要创建红黑树这种数据结构 在上篇我们了解了AVL树 既然已经有了AVL这种平衡的二叉排序树 为什么还要有红黑树呢 AVL树通过定义我们知道要求树中每一个结点的左右子树高度差的绝对值不超过1 其是一颗严格的平衡树 这样构建