快速理解红黑树原理

article/2025/11/3 7:58:01

快速理解红黑树原理

红黑树 简介

红黑树 其实就是一个二叉树。


    1.0 常用的二叉树类型

    简单说二叉树概念:
    二叉树 又称度为至多二的树。

    1.1 平衡二叉树

    平衡二叉树又称 AVL 树
    特点:一个根节点的左右个子树的高度差不超过1

    平衡二叉树

    这里写图片描述

    非平衡二叉树

    这里写图片描述
    高度差已经大于1 了。
    平衡树解决的问题就是 能够最大限度的增加访问的每个节点的的平均性
    。保证每个节点被访问的次数平衡。



    1.2 完全二叉树

    除最后一层外,每一层上的结点数均达到最大值;在最后一层上只缺少右边的若干结点。
    这里写图片描述
    堆排序 结构其实就是一个完全二叉树的结构,倒序和正序就是用的 大根堆 小根堆的原理。


    1.3 满二叉树

    每个节点是叶节点或者度为2.
    这里写图片描述


    1.4 查找二叉树

    这种树的特点是 每个根节点大于左子树上的任意一个节点,小于等于右子树上的任意一个节点。
    这里写图片描述
    举个简单例子:
    比如说 我现在要查找 4 这个数字 ,首先 我先比较 根节点就行,如果比根节点小的话,那么肯定在左边的子树列表里面。那么右边的就不用看了。然后依次同理比较。
    查找二叉树 能够提高查询速度的效率。

    但是还有一种情况 比较特殊:
    这里写图片描述
    这样的 比较尴尬了,一边倒的情况它也满足查找二叉树的概念。但是效率就不那么高效了。

    在说原理之前说一下
    高度与深度区别:

    • 深度定义是从上往下的
    • 高度定义是从下往上的
    • 空数高度0
    • 叶子结点高度1

    在这里插入图片描述
    在这里插入图片描述
    目前很多网上说法不一致 ,大概如上图两种情况 这紫色,橙色代表层数
    一般情况 根节点 根节点 是从0 或者 1

    此时树的深度为 3 高度 为 9–4–2–1 =4
    针对一颗树来说

    •  根结点0紫色,层数=深度=高度-1根结点1橙色,层数=深度=高度
      

    但是针对每一个树上的节点而言

    •  相同深度的每个结点,高度不一定相同,因为每个结点下面的叶结点的深度是不一定相同的
      

    如图:②④⑤ 他们高度 3 2 1 深度 1 2 2

    2.0 红黑树原理

    2.1 红黑树结构核心法则

    1. 每个节点要么是红色,要么是黑色
    2. 根节点【NULL】必须是黑色
    3. 节点是红色不能连续(如果节点是红色 ,孩子必须是黑色
    4. 从任意节点出发到其NULL节点 的简单路径上都包含相同数目的黑色节点★★★ (关键)
    5. 每个红色节点的两个子节点一定都是黑色(叶子节点包含NULL)

    2.2 红黑树的结构

    如图
    这里写图片描述
    红黑树从根节点到每个叶子节点的路径都包含相同数量的黑色节点,因此从根节点到叶子节点的路径中包含的黑色节点数被称为树的“黑色高度(black-height)

    一颗树黑色高度为3得红黑树,从根结点到叶结点的最短路径长度是3(黑-黑-黑),最长路径为4(黑-红-黑-红-黑)。由于第4条性质,不可能在最长路径中加入更多的黑色结点,因为性质3规定红色结点的子结点必须是黑色的,因此在同一简单路径中不允许有两个连续的红色结点。红黑树中最长路径就是一条红黑交替的路径
    对于给定的黑色高度为n的红黑树,从根结点到叶结点的简单路径的最短长度为n-1,最大长度为2(n-1)。所有对树的操作必须保持上面列出的属性。特别要指出的是,插入和删除树的结点的操作必须遵循这些原则。

    2.3 红黑树插入流程

    2.3.1 核心策略

    • 插入节点且将颜色染成红色
    • 重新染色 且基于 《红黑树核心法则2.1》 旋转 修复

    2.3.1.1 为什么要将节点染成 红色?

    插入的节点染成红色 会破坏 2 、3 法则,便于后续修复
    在这里插入图片描述

    2.3.2 插入常见几种情况

    在这里插入图片描述

    1. 红黑树结构不会旋转变化情况:
      1)当插入的节点为的父亲为黑色节点。【什么都不用做】
      2)被插入的节点是根节点。【直接把此节点涂为黑色】
    2. 红黑树结构发生旋转变化情况:
      1) 当前节点的父节点【60】是红色,且当前节点的祖父节点【40】的另一个子节点(叔叔节点)也是红色。
      2)当前插入的父节点是红色,当前叔叔节点的黑色,且当前节点为其父亲节点的左孩子。(进行左旋)
      3)当前插入的父节点是红色,当前叔叔节点的黑色,且当前节点为其父亲节点的右孩子。(进行右旋)

    如图 所示
    图片后续更新一版【】

    红黑树结构发生旋转变化情况已经对应的措施如下
    这里写图片描述

    左旋 : 右边过于臃肿
    右旋 : 左边过于臃肿
    相对复杂的红黑树 旋转最大不超过3次
    下面展示一个红黑树插入数据过程
    在这里插入图片描述

    树的旋转问题

    1.为什么会出现旋转?
    对于平衡树来说,当插入或者删除的时候,树的结构会发生破坏因此会导致。因此需要对树进行旋转来保证树的平衡。

    先拿 平衡二叉树的 查找二叉树举一个例子:
    这里写图片描述
    此时当前二叉树 是新增一个60数字红色。 此时 当前二叉树不平衡了,那么需要进行左旋 需要把当前40 那个节点作为跟节点,然后把30和20 旋转下来。
    这里写图片描述

    此时大家发现这样还是会有问题。发现又不满足二叉树了,现在变三叉了,不要急 ,此时再次挑战需要把中间的 33 那个分支砍掉,接在哪边呢?根据查找二叉树的规则,比根节点小的放在左边,比根节点大的放在右边。 33 比40 小 但是 比30 大。如图
    这里写图片描述

    红黑树应用

    TreeMap 典型红黑树
    Android Binder 虚拟内存 Intent IPC 1M 小内存块
    TreeMap

    左旋代码:

    //左旋右侧需要平衡private void rotateLeft(Entry<K,V> p) {if (p != null) {//拿到根节点的右子节点 Entry<K,V> r = p.right;//把根节点的右子节点的左节点,赋值p.right = r.left;if (r.left != null)//将根节点这个值赋值到当前断开的跟节点上r.left.parent = p;//r 将来要成为新的根节点 p.parent 为根 ,使得他为新的跟节点 r.parent = p.parent;if (p.parent == null)root = r;//如果p 为左孩子,让他还是成为左孩子 同理else if (p.parent.left == p)p.parent.left = r;elsep.parent.right = r;//最后 将当前交换的跟换值r.left = p;p.parent = r;}}
    

    右旋代码:

     private void rotateRight(Entry<K,V> p) {if (p != null) {Entry<K,V> l = p.left;p.left = l.right;if (l.right != null) l.right.parent = p;l.parent = p.parent;if (p.parent == null)root = l;else if (p.parent.right == p)p.parent.right = l;else p.parent.left = l;l.right = p;p.parent = l;}}
    

    插入元素:

      public V put(K key, V value) {Entry<K,V> t = root;if (t == null) {compare(key, key); // type (and possibly null) checkroot = new Entry<>(key, value, null);size = 1;modCount++;return null;}int cmp;Entry<K,V> parent;// split comparator and comparable pathsComparator<? super K> cpr = comparator;if (cpr != null) {do {parent = t;cmp = cpr.compare(key, t.key);if (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;elsereturn t.setValue(value);} while (t != null);}else {if (key == null)throw new NullPointerException();@SuppressWarnings("unchecked")Comparable<? super K> k = (Comparable<? super K>) key;do {parent = t;cmp = k.compareTo(t.key);if (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;elsereturn t.setValue(value);} while (t != null);}Entry<K,V> e = new Entry<>(key, value, parent);if (cmp < 0)parent.left = e;elseparent.right = e;fixAfterInsertion(e);size++;modCount++;return null;}
    

    红黑树相关定理

    1. 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。

      根据上面的性质5我们知道上图的红黑树每条路径上都是3个黑结点。因此最短路径长度为2(没有红结点的路径)。再根据性质4(两个红结点不能相连)和性质1,2(叶子和根必须是黑结点)。那么我们可以得出:一条具有3个黑结点的路径上最多只能有2个红结点(红黑间隔存在)。也就是说黑深度为2(根结点也是黑色)的红黑树最长路径为4,最短路径为2。从这一点我们可以看出红黑树是 大致平衡的。 (当然比平衡二叉树要差一些,AVL的平衡因子最多为1)

    2. 红黑树的树高(h)不大于两倍的红黑树的黑深度(bd),即h<=2bd

      根据定理1,我们不难说明这一点。bd是红黑树的最短路径长度。而可能的最长路径长度(树高的最大值)就是红黑相间的路径,等于2bd。因此h<=2bd。

    3**. 一棵拥有n个内部结点(不包括叶子结点)的红黑树的树高h<=2log(n+1)**

      下面我们首先证明一颗有n个内部结点的红黑树满足n>=2^bd-1。这可以用数学归纳法证明,施归纳于树高h。当h=0时,这相当于是一个叶结点,黑高度bd为0,而内部结点数量n为0,此时0>=2^0-1成立。假设树高h<=t时,n>=2^bd-1成立,我们记一颗树高 为t+1的红黑树的根结点的左子树的内部结点数量为nl,右子树的内部结点数量为nr,记这两颗子树的黑高度为bd'(注意这两颗子树的黑高度必然一 样),显然这两颗子树的树高<=t,于是有nl>=2^bd'-1以及nr>=2^bd'-1,将这两个不等式相加有nl+nr>=2^(bd'+1)-2,将该不等式左右加1,得到n>=2^(bd'+1)-1,很显然bd'+1>=bd,于是前面的不等式可以 变为n>=2^bd-1,这样就证明了一颗有n个内部结点的红黑树满足n>=2^bd-1。在根据定理2,h<=2bd。即n>=2^(h/2)-1,那么h<=2log(n+1)从这里我们能够看出,红黑树的查找长度最多不超过2log(n+1),因此其查找时间复杂度也是O(log N)级别的。
    

    红黑树的优势

    红黑树 优势
    红黑树能够以O(log2(N))的时间复杂度进行搜索、插入、删除操作。此外,任何不平衡都会在3次旋转之内解决。这一点是AVL所不具备的

    以上是本人学习红黑树的相关体会和心得。
    本文章学习相关内容是转载
    http://www.cnblogs.com/skywang12345/p/3245399.html
    https://www.cnblogs.com/gofighting/p/5437998.html
    https://blog.csdn.net/qq_36667170/article/details/84142019
    如果有兴趣的同学很可以去这个链接继续学习一下。


    http://chatgpt.dhexx.cn/article/wKocaSu6.shtml

    相关文章

    数据结构-红黑树原理分析

    前言 在阅读HashMap源码的时候发现&#xff0c;java1.8的HashMap的链表实现增加了红黑树&#xff0c;当链表长度超过指定阈值8的时候回进行树化。 为了提高增删查的效率。 而红黑树又比较复杂&#xff0c;所以专门写一篇关于红黑树的文章。 概念 R-B Tree&#xff0c;全称是…

    红黑树原理剖析

    首先介绍一下红黑树的几点性质: 性质1:根节点是黑色 性质2:每个叶子节点是黑色(指的是空叶子节点) 性质3:每个红色节点的两个子节点一定是黑色 (子节点必须同时存在或不存在) 性质4:任意一节点到每个叶子节点的路径都包含数量相同的黑节点(非空叶子…

    红黑树原理及插入

    文章目录 1、前言2、红黑树2.1、性质2.2、操作2.2.1、变色2.2.2、左旋2.2.3、右旋2.2.4、查找2.2.5、插入 2.3、插入情景2.3.1、红黑树为空树2.3.2、插入结点的Key已存在2.3.3、插入结点的父结点为黑结点2.3.4、插入节点的父节点为红色2.3.4.1、叔叔结点存在并且为红结点 2.3.5…

    红黑树原理及代码实现(一)

    红黑树简介 红黑树是一种自平衡的二叉查找树&#xff0c;它的统计性能要优于平衡二叉树&#xff0c;因此在很多地方都有应用&#xff0c;例如Java中的TreeMap&#xff0c;HashMap等数据结构都使用到了红黑树。红黑树对很多人来说熟悉而陌生&#xff0c;熟悉则是因为知道红黑树…

    图解红黑树原理

    一.红黑树的性质&#xff08;一种自平衡的二叉查找树&#xff09; 1. 根节点是黑色。 2. 节点是红色或黑色 3. 叶子节点都是黑色的空节点&#xff08;NIL节点&#xff09; 意思就是末尾一排是黑色空节点&#xff08;可全部省略&#xff09; &#xff08;叶子节点意思是没有子…

    红黑树原理和算法详细介绍

    目录 1 R-B Tree简介 2 红黑树的时间复杂度和相关证明 3 红黑树的基本操作 1. 左旋 2. 右旋 3. 添加 4.1 删除 1 R-B Tree简介 R-B Tree&#xff0c;全称是Red-Black Tree&#xff0c;又称为“红黑树”&#xff0c;它一种特殊的二叉查找树。红黑树的每个节点上都有存储…

    HashMap底层红黑树原理(超详细图解)+手写红黑树代码

    在看完了小刘老师和黑马的源码视频之后,我整理了一篇HashMap的底层源码文章&#xff0c;学海无涯&#xff0c;这几天看了对红黑树的讲解&#xff0c;故将其整理出来 HashMap底层源码解析上 HashMap底层源码解析下 视频链接 小刘老师讲源码 传智播客-黑马程序员 文章目录 树结…

    红黑树原理及java实现

    红黑树 红黑树规则特点&#xff1a; 节点分为红色或者黑色&#xff1b;根节点必为黑色&#xff1b;叶子节点都为黑色&#xff0c;且为null&#xff1b;连接红色节点的两个子节点都为黑色&#xff08;红黑树不会出现相邻的红色节点&#xff09;&#xff1b;从任意节点出发&…

    红黑树原理及旋转

    红黑树&#xff0c;本质上来说就是一棵二叉查找树 但它在二叉查找树的基础上增加了着色和相关的性质使得红黑树相对平衡 保证了红黑树的查找、插入、删除的时间复杂度最坏为O(log n) 但它是如何保证一棵n个结点的红黑树的高度始终保持在h logn的呢&#xff1f;这就引出了红黑…

    HashMap红黑树原理分析

    近期学习了 HashMap 实现原理&#xff0c;这篇咱们了解一下红黑树的设计&#xff0c;相比 jdk1.7 的 HashMap 而言&#xff0c;jdk1.8最重要的就是引入了红黑树的设计&#xff0c;当hash表的单一链表长度超过 8 个的时候&#xff0c;链表结构就会转为红黑树结构。 01、故事的起…

    HashMap源码学习:红黑树原理详解

    文章导航 HashMap源码学习&#xff1a;红黑树原理详解 HashMap源码学习&#xff1a;JDK1.8版本源码解析 目录 文章导航前言概述红黑树的特性变色平衡右旋平衡左旋平衡 正文红黑树平衡方法&#xff1a;balanceInsertion红黑树左旋方法&#xff1a;rotateLeft红黑树右旋方法&…

    红黑树原理讲解

    红黑树原理讲解 一、红黑树的性质二、红黑树的3种变化策略&#xff1f;&#xff08;为满足红黑树性质&#xff09;1. 改变颜色2. 左旋3. 右旋 三、红黑树的插入情景1&#xff1a;红黑树为空树情景2&#xff1a;插入节点的key已经存在情景3&#xff1a;插入节点的父节点为黑色情…

    红黑树原理详解

    红黑树原理详解 红黑树的旋转红黑树上结点的插入红黑树上结点的删除 参考&#xff1a; 教你初步了解红黑树 红黑树(一)之 原理和算法详细介绍 红黑树定义&#xff1a; (1) 每个节点或者是黑色&#xff0c;或者是红色。 (2) 根节点是黑色。 (3) 每个叶子节点是黑色。 [注意&…

    红黑树原理

    因为看的时候写在了纸上&#xff0c;于是直接扫描的&#xff0c;效果不太好。

    HashMap红黑树原理解析

    HashMap红黑树原理解析 定义&#xff1a; 简单来说红黑树是一种近视平衡二叉查找树&#xff0c;主要优点是”平衡”&#xff0c;即左右子树高度几乎一致&#xff0c;以此来防止树退化为链表&#xff0c;通过这种方式来保障查找的时间复杂度为log(n)。 下面先主要提一下红黑树…

    红黑树的原理及实现

    红黑树的原理及实现 一、什么是红黑树二、定义红黑树三、左旋和右旋四、红黑树插入节点 一、什么是红黑树 红黑树是一种特定类型的二叉树&#xff0c;它是在计算机科学中用来组织数据比如数字的块的一种结构。 红黑树是一种平衡二叉查找树的变体&#xff0c;它的左右子树高差有…

    【图文详解】彻底了解红黑树底层实现原理

    红黑树定义 红黑树&#xff08;Red Black Tree&#xff09; 是一种自平衡二叉查找树&#xff0c;是在计算机科学中用到的一种数据结构&#xff0c;典型的用途是实现关联数组。 红黑树是一种特化的AVL树&#xff08;平衡二叉树&#xff09;&#xff0c;都是在进行插入和删除操…

    红黑树(一)之 原理和算法详细介绍

    概要 目录1 红黑树的介绍2 红黑树的应用3 红黑树的时间复杂度和相关证明4 红黑树的基本操作(一) 左旋和右旋5 红黑树的基本操作(二) 添加6 红黑树的基本操作(三) 删除 作者&#xff1a;Sky Wang 于 2013-08-08 概述&#xff1a;R-B Tree&#xff…

    数据结构 | 【红黑树】图解原理

    今天我们要说的红黑树就是就是一棵非严格均衡的二叉树&#xff0c;均衡二叉树又是在二叉搜索树的基础上增加了自动维持平衡的性质&#xff0c;插入、搜索、删除的效率都比较高。红黑树也是实现 TreeMap 存储结构的基石。 红黑树就是非严格均衡的二叉搜索树。 一、红黑树规则特…

    红黑树原理简单解析

    一、红黑树为什么会出现呢&#xff1f; 是因为二叉搜索树有可能会出现极端的情况&#xff0c;就是只有一侧有数据&#xff0c;那这样的话就会降级为链表。后来出现了平衡二叉树&#xff0c;但是由于强制平衡所导致付出的代价比较高昂&#xff0c;所以黑红树出现了。 二、简介…