没有对象来和我手撕红黑树吧

1. 红黑树的介绍

红黑树也是一种自平衡的二叉搜索树,在每一个节点增加了一个存储位来表示节点的颜色,可以是红色也可以是黑色,通过约束颜色来维持树的平衡,具有以下的性质:

  1. 每个节点不是红色就是黑色
  2. 根节点为黑色
  3. 如果一个节点为红色,那么它的两个孩子节点为黑色(一条路径上不能有两个连续的红色节点)
  4. 对于每个节点,从该节点及其所有后代所在的叶子节点的简单路径上,均包含相同数目的黑色节点
  5. 每一个叶子节点都是黑色的

2. 节点的定义

这里节点除了包含节点的值,左子树,右子树和父亲节点的引用外,还需要添加颜色的属性

static class RBTreeNode {
    public RBTreeNode left;
    public RBTreeNode right;
    public RBTreeNode parent;
    public int val;
    public COLOR color;

    public RBTreeNode(int val) {
        this.val = val;
        //新创建的节点默认是红色的
        this.color = COLOR.RED;
    }
}

颜色只有红色和黑色,可以使用枚举类来定义节点的颜色

public enum COLOR {
    RED,BLACK
}

节点默认创建为红色的原因:如果节点是黑色,那么插入时就会增加该路径黑色节点的个数,其他路径都需要增加黑色节点,节点是红色的话就不会影响黑色节点的个数,如果上一个节点也是红色,只需要向上调整节点的颜色即可

3. 插入

在寻找插入到哪个位置时,也是和二叉搜索树一样的,(需要注意的是,第一次插入之后需要手动的把 root 节点的颜色修改为黑色)当找到插入的位置之后,可以分为一下几种情况

3.1. p 是左子树

  1. cur 为红色, p 为红色,g 为黑色,u 存在且为红色

两个红色不能连在一起,此时就必须把 p 修改为黑色,然后为了保持黑色是相同的, u 也需要修改为黑色

这个时候就会有一个问题,如果 g 是一个黑色节点的子树,那么这时修改 p , u 就会增加黑色节点的数目,就需要把 g 改为红色,假如 g 就是根节点的话,还是需要把 g 改回黑色,所以说最后处理完之后,无论 g 当前是红色还是黑色,都手动的改为黑色

那如果 g 的父亲节点本身就是红色的话,证明它一定是有父亲节点的,然后按照上面的方式调整之后继续向上调整即可

  1. cur 为红色且是左节点,p 为红色,g 为黑色,u 不存在或者是黑色

如果 u 不存在,那么 cur 一定是新插入的节点,原来的肯定是不能有两个连续的红色节点的

当 u 存在且为黑色的时候

这种情况在调整的过程中会出现

对于这种情况的解决方案就是,先右旋 p ,再调整颜色

  1. cur 为红且是右节点,p 为红,g 为黑,u 不存在或 u 为黑

这种情况也应该是调整过程中出现的

此时对 p 进行一个左旋,然后交换 cur 和 p 的引用,就变成了第二种情况,继续按照第二种的情况调整就好

3.2. p 是右子树

然后就是 p 是右子树的情况,也是和上面一样的三种情况:

  1. cur 为红色, p 为红色,g 为黑色,u 存在且为红色

这种情况和上面的是一样的

  1. cur 为红色且是右节点,p 为红色,g 为黑色,u 不存在或者是黑色

只不过这次是需要右旋的,其余步骤还是和之前一样

  1. cur 为红且是左节点,p 为红,g 为黑,u 不存在或 u 为黑

当以上所有的情况都考虑完之后,还需要手动的把 root 节点的颜色改为黑色

4. 红黑树的验证

验证的话主要就是验证有没有两个红色节点相连和每条路径的黑色节点数量是否相等

先来看红色节点是否相连:只需要在遍历的过程中遇到红色节点之后,去看它的父亲节点是否是红色的即可,然后递归执行

    private boolean checkRedColor(RBTreeNode root){
        if(root == null) return true;
        if(root.color == COLOR.RED){
            RBTreeNode parent = root.parent;
            if(parent.color == COLOR.RED){
                System.out.println("两个红色节点连续了");
                return false;
            }
        }
        return checkRedColor(root.left) && checkRedColor(root.right);
    }

判断每条路径黑色节点的数量是否相同:首先求出一条路径的黑色节点的数量,然后再遍历每条路径,同时统计路径上的黑色节点的个数,和开始计算的出的黑色节点个数对比,如果不相同那么就不满足红黑树的性质

private boolean checkBlackNum(RBTreeNode root,int pathBlackNum,int blackNum){
    if(root == null) return true;
    if(root.color == COLOR.BLACK){
        pathBlackNum++;
    }
    if(root.left == null && root.right == null){
        if(pathBlackNum != blackNum){
            System.out.println("黑色节点不符合要求");
            return false;
        }
    }
    return checkBlackNum(root.left,pathBlackNum,blackNum)&&
    checkBlackNum(root.right,pathBlackNum,blackNum);
}

最后把这两种情况都结合起来,同时还需要判断根节点的颜色是否是黑色

public boolean isRBTree(){
    if(root == null) return true;
    //根节点必须为黑色
    if(root.color != COLOR.BLACK) return false;
    //存储当前红黑树中的黑色节点个数
    int blackNum = 0;
    RBTreeNode cur = root;
    while(cur!=null){
        if(cur.color == COLOR.BLACK){
            blackNum++;
        }
        cur = cur.left;
    }
    //检查是否存在两个连续的红色节点和每条路径的黑色节点是否相同
    return checkRedColor(root) && checkBlackNum(root, 0, blackNum);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/904311.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

怎么实现电脑控制100台手机,苹果手机群控系统不用越狱实现新突破

今天来给大家介绍一款软件——手机群控。 什么是手机群控?就是将多台手机同时连接至一台电脑,集中控制管理。 对于苹果iOS免越狱中控,此前一直是个难题。 毕竟iOS系统封闭性极强,且苹果官方限制了USB的传输类型,只允…

【网络面试篇】TCP与UDP类

目录 一、综述 1. TCP与UDP的概念 2. 特点 3. 区别 4. 对应的使用场景 二、补充 1. 基础概念 (1)面向连接 (2)可靠的 (3)字节流 2. 相关问题 (1)TCP 和 UDP 可以同时绑定…

web自动化测试平台开发之核心执行器

web自动化测试平台开发之核心执行器 一、如何从自动化框架到核心执行器二、核心执行器框架逻辑梳理三、核心执行器利用命令驱动执行 一、如何从自动化框架到核心执行器 脚本:底层用了三个内容:pythonpytestselenium,线性脚本,只是单纯的把功能测试用例转…

AI自媒体变现路径大盘点!建议收藏!

当下的我做为一人公司或者超级个体为目标的创业模式,无论是在写作、图文和短视频输出方面,我都是运用了N个AI工具来提升我的生产力。 这种创业模式就是一个人N个AI的模式,我们可以通过AI工具做提效来赚取差价,以时间复利来累计财…

Boost电路双闭环控制MATLAB仿真

一、Boost电路电流内环控制MATLAB仿真模型 1.MATLAB仿真模型 1.1.仿真模型图 因为要使用电流内环控制,相比较于开环控制中直接给定MOS开关的占空比,这里通过把电路的平均电流和一电流基准值相比较来控制MOS开关的占空比,因此称为闭环控制。…

centos7 zabbix监控nginx的pv和uv和status_code

zabbix监控nginx的pv: pv)cat /var/log/nginx/access.log|awk {print $1}|wc -l;;zabbix-get验证: [rootbogon ~]# zabbix_get -s 192.168.253.231 -k pv_uv[pv] 100zabbix监控nginx的uv uv)cat /var/log/nginx/access.log|awk {print $1}|uniq -c | w…

分布式系统理论基础:Raft、Zab

目录 引言RaftZabPaxos、Raft、Zab再比较小结 该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解分布式理论中的基本概念,常见算法、以及一些较为复杂的分布式原理,同时也需要进一步了解…

Ubuntu 20.04 安装 OpenCV 和 OpenCV_contrib 教程

Ubuntu 20.04 安装 OpenCV 和 OpenCV_contrib 教程 Ubuntu 20.04 安装 OpenCV 和 OpenCV_contrib 教程前言 OpenCV概述核心功能优势特点应用领域安装与使用 OpenCV_contrib概述核心功能具体模块 安装与使用一、准备工作二、下载OpenCV和OpenCV_contrib三、编译和安装OpenCV四、…

【鸿蒙HarmonyOS实战:通过华为应用市场上架测试版App实现HBuilder X打包的UniApp项目的app转hap教程(邀请码)方式教程详解】

鸿蒙HarmonyOS实战:通过华为应用市场上架测试版App实现HBuilder X打包的UniApp项目的app转hap教程(邀请码)方式详解 在使用uniapp打包的鸿蒙项目的过程中,由于生成的是app文件,而hdc传给鸿蒙HarmonyOS系统需要的是hap文…

HarmonyOS 5.0应用开发——应用打包HAP、HAR、HSP

【高心星出品】 目录 应用打包HAP、HAR、HSPModule类型HAPHAR创建HAR建立依赖HAR共享内容 HSP创建HSP建立依赖同上HSP共享内容同上 HAR VS HSP 应用打包HAP、HAR、HSP 一个应用通常会包含多种功能,将不同的功能特性按模块来划分和管理是一种良好的设计方式。在开发…

数据结构————map,set详解

今天带来map和set的详解&#xff0c;保证大家分清楚 一&#xff0c;概念 map和set是一种专门用来搜索的容器或数据结构 map能存储两个数据类型&#xff0c;我们称之为<key-value>模型 set只能存储一个数据类型&#xff0c;我们称之为纯<key>模型 它们的效率都非…

Vue.js(2): 组件与路由基础指南

这一路上可能会有艰辛、困难、疑惑、付出、泪水、失败&#xff0c;但是一定要享受这个过程&#xff0c;因为所有的失败都是为了下一刻的成功 文章目录 组件什么是组件组件化开发的好处组件底层是什么全局注册组件局部注册组件组件嵌套组件命名规则组件传值 SPAvue-router路由动…

[c++高阶]二叉搜索树深度剖析

1.前言 从二叉搜索树开始&#xff0c;后面慢慢学的AVL树&#xff0c;红黑树&#xff0c;map,set&#xff0c;哈希表等等都会慢慢的变得更难了&#xff0c;也更加难以理解了。希望大家能够坚持下去&#xff0c;只要坚持&#xff0c;就是胜利。 本章重点 着重讲解什么是二叉搜索…

【力扣刷题实战】单值二叉树

大家好&#xff0c;我是小卡皮巴拉 文章目录 目录 力扣题目&#xff1a; 单值二叉树 题目描述 示例 1&#xff1a; 示例 2&#xff1a; 解题思路 题目理解 算法选择 具体思路 解题要点 完整代码&#xff08;C语言&#xff09; 兄弟们共勉 &#xff01;&#xff01;…

MySQL数据库MHA高可用

目录 一、MHA简述 二、MHA 的组成 三、MHA 的特点 四、MHA工作原理 五、MHA部署步骤 六、搭建 MySQL MHA MHA一主两从高可用集群示意图 实验环境 1. Master、Slave1、Slave2 节点上安装 mysql5.7 2. 关闭防火墙 3. 修改 Master、Slave1、Slave2 节点的主机名 4. 修…

国内短剧源码短剧系统搭建小程序部署H5、APP打造短剧平台

​在当今的互联网时代&#xff0c;短剧作为一种新兴的娱乐形式&#xff0c;受到了越来越多用户的喜爱。为了提供更好的用户体验和满足用户需求&#xff0c;一个好的短剧系统需要具备多元化的功能和优质的界面设计。 本文将介绍国内短剧源码短剧系统搭建小程序部署H5、APP所需的…

【传知代码】图像处理解决种子计数方法

文章目录 一、背景及意义介绍研究背景农业考种需求传统计数方法的局限性人工计数仪器设备计数 研究意义提高育种效率提高计数准确性广泛的适用性数据存档与分析便利 二、概述三、材料与数据准备以及方法介绍整体流程图像采集图像预处理形态学操作腐蚀运算开运算 图像二值化种子…

Typora一款极简Markdown文档编辑器和阅读器,实时预览,序列号生成!免费!最新可用!

文章目录 一、Typora下载和安装二、Typora序列号生成 Typora是一款Markdown编辑器和阅读器&#xff0c;风格极简&#xff0c;实时预览&#xff0c;所见即所得&#xff0c;支持MacOS、Windows、Linux操作系统&#xff0c;有图片和文字、代码块、数学公式、图表、目录大纲、文件管…

C/C++(八)C++11

目录 一、C11的简介 二、万能引用与完美转发 1、万能引用&#xff1a;模板中的 && 引用 2、完美转发&#xff1a;保持万能引用左右值属性的解决方案 三、可变参数模板 1、可变参数模板的基本使用 2、push 系列和 emplace 系列的区别 四、lambda表达式&#xf…

海亮科技亮相第84届中国教装展 尽显生于校园 长于校园教育基因

10月25日&#xff0c;第84届中国教育装备展示会&#xff08;以下简称“教装展”&#xff09;在昆明滇池国际会展中心开幕。作为国内教育装备领域规模最大、影响最广的专业展会&#xff0c;本届教装展以“数字赋能教育&#xff0c;创新引领未来”为主题&#xff0c;为教育领域新…