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

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);
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入理解gPTP时间同步过程

泛化精确时间协议(gPTP)是一个用于实现精确时间同步的协议,特别适用于分布式系统中需要高度协调的操作,比如汽车电子、工业自动化等。 gPTP通过同步主节点(Time Master)和从节点(Time Slave)的时钟,实现全局一致的时间参考。 以下是gPTP实现主从时间同步的详细过程:…

rom定制系列------红米note8_miui14安卓13定制修改固件 带面具root权限 刷写以及界面预览

💝💝💝红米note8机型代码:ginkgo。高通芯片。此固件官方最终版为稳定版12.5.5安卓11的版本。目前很多工作室需要高安卓版本的固件来适应他们的软件。并且需要root权限。根据客户要求。修改固件为完全root。并且修改为可批量刷写的…

MicroServer Gen8再玩 OCP万兆光口+IT直通之二

这个接上一篇,来个简单测试。 一、测试环境 PC端:Win10,网卡:万兆光纤(做都做了,都给接上),硬盘使用N年的三星SSD 840 交换机:磊科GS10,带两个万兆口 Gen…

怎么理解ES6 Proxy

Proxy 可以理解成,在目标对象之前架设一层 “拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来 “代理…

揭秘代码界的新挑战:低代码平台,为何让程序员头疼不已?

我最近在网上看到一个很有趣的话题:为什么程序员大多讨厌低代码?好家伙,这一下子就将低代码推到了程序员的对立面,两者直接到了水火不容的地步。 其实低代码倒也不是什么新鲜事物,它是一种只需用很少甚至不需要代码即可…

APP如何提升关键词排名?

提升关键词排名是ASO(App Store Optimization)策略中的关键环节,以下是一些有效的方法来提高App在应用商店中的关键词排名: 1. **关键词研究**: - 使用专业的ASO工具进行关键词研究,找出与你的App相关且…

ClickHouse 3节点集群安装

ClickHouse 简介 ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS)。 官方网站:https://clickhouse.com/ 项目地址:https://github.com/ClickHouse/ClickHouse 横向扩展集群介绍 此示例架构旨在提供可扩展性。它包括三个节点&#xff…

基于springboot的在线投票系统,比赛实时投票平台的实现

1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.硬件环境:windows 7…

UE4安卓打aab包时,同时存在“gradle”、“arm64/gradle”两个Gradle工程的原因

两个Gradle工程的现象 在出安卓aab包时,观察到存在以下两个Gradle工程: 1、Intermediate\Android\arm64\gradle (称为arm64的Gradle) 2、Intermediate\Android\gradle(称为根下的Gradle) 它们存在一些小…

在IDEA中运行Mybatis后发现取出的password值为null

问题: 解决方案:修改sql文如下(取别名) Select("select id,name,pwd as password from user where id #{id}") 重新运行即可

股票基础交易规则!最小变动数量规则!最大数量限制规则!

股票基础交易规则系列 数量规则 01 最小变动数量规则 沪深主板、创业板:单笔申报数量应当为100股或其整数倍。 科创板:单笔申报数量应当不小于200股,1股递增。 北交所:单笔申报数量应当不小于100股,1股递增。 举例…

Selenium自动化测试框架详解

🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 设计思路 本文整理归纳以往的工作中用到的东西,现汇总成基础测试框架提供分享。 框架采用python3 selenium3 PO yaml ddt unittest等技术编写…

ChangeCLIP环境配置

看到有个现成的dockerfile,先试试 ok首先需要root权限的用户 才能用docker,其次要外网,要不然有些东西好像下载不了 (失败) 那就直接配吧 我看12服务器上有个openmmlab的环境,先基于这个环境吧 # 用lx账…

【MATLAB源码-第272期】基于matlab的OMP算法的毫米波MIMO通信系统的混合波束成形仿真。

操作环境: MATLAB 2022a 1、算法描述 在现代无线通信系统中,随着频谱资源的日益紧张,毫米波(mmWave)技术成为5G及未来通信系统的重要组成部分。毫米波频段的宽频带提供了远超传统微波频段的频谱资源,能够…

【python】OpenCV—findContours(4.3)

文章目录 1、功能描述2、代码实现3、完整代码4、结果展示5、涉及到的库函数5.1、cv2.Canny5.2 cv2.boxPoints 6、参考 1、功能描述 找出图片中的轮廓,拟合轮廓外接椭圆和外接矩阵 2、代码实现 导入必要的库,固定好随机种子 import cv2 as cv import …

直播推流和拉流--系统篇

今天实现一下直播推流和拉流。服务器端使用opencloudos8系统。顺便把我之前写的小系统弄上去跑跑,搭建个git服务器,使用ssh协议,密钥方式。 先展示一下在iphone上推流效果图 再展示下在谷歌浏览器上的拉流效果图,safari浏览器和微…

安全芯片 OPTIGA TRUST M 使用介绍与示例(基于STM32裸机)

文章目录 目的资料索引硬件电路软件框架介绍数据存储框架移植框架使用 使用示例示例地址与硬件连接通讯测试功能测试 总结 目的 OPTIGA TRUST M 是英飞凌推出的安全芯片,芯片通提供了很多 slot ,用于存放各类安全证书、密钥、用户数据等,内置…

数据结构 之 二叉树遍历 ------中序(根)遍历 和 后序(根)遍历(六)

提示:本篇章主要讲解数据结构中树的相关知识。 文章目录 中序(根)遍历二叉树(LTR)后序(根)遍历二叉树(LRT)中根遍历二叉树的递归算法 (重要)后序遍历二叉树的…

数据结构 ——— 二叉树的概念及结构

目录 二叉树的概念 特殊的二叉树 一、满二叉树 二、完全二叉树 二叉树的概念 二叉树树示意图: 从以上二叉树示意图可以看出: 二叉树每个节点的度不大于 2 ,那么整个二叉树的度也不大于 2 ,但是也不是每个节点都必须有 2 个…

IDEA解决 properties 文件乱码问题

博主介绍: 计算机科班人,全栈工程师,掌握C、C#、Java、Python、Android等主流编程语言,同时也熟练掌握mysql、oracle、sqlserver等主流数据库,具有丰富的项目经验和开发技能。提供相关的学习资料、程序开发、技术解答、…