HashMap红黑树原理分析

article/2025/11/3 15:44:30

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

01、故事的起因

JDK1.8 最重要的就是引入了红黑树的设计(当key值的hash值相同的链表长度超过 8 个的时候)
为什么要这样设计呢?好处就是避免在最极端的情况下链表变得很长很长,在查询的时候,效率会非常慢。

在这里插入图片描述

  • 红黑树查询:其访问性能近似于折半查找,时间复杂度 O(logn);
  • 链表查询:这种情况下,需要遍历全部元素才行,时间复杂度 O(n);

本文主要是讲解红黑树的实现,只有充分理解了红黑树,对于之前的分析才会更加理解。

简单的说,红黑树是一种近似平衡的二叉查找树,其主要的优点就是“平衡“,即左右子树高度几乎一致,以此来防止树退化为链表,通过这种方式来保障查找的时间复杂度为 log(n)。

在这里插入图片描述

关于红黑树的内容,网上给出的内容非常多,主要有以下几个特性:

  • 1、每个节点要么是红色,要么是黑色,但根节点永远是黑色的;

  • 2、每个红色节点的两个子节点一定都是黑色;

  • 3、红色节点不能连续(也即是,红色节点的孩子和父亲都不能是红色);

  • 4、从任一节点到其子树中每个叶子节点的路径都包含相同数量的黑色节点;

  • 5、所有的叶节点都是是黑色的(注意这里说叶子节点其实是上图中的 NIL 节点);

在树的结构发生改变时(插入或者删除操作),往往会破坏上述条件 3 或条件 4,需要通过调整使得查找树重新满足红黑树的条件。

02、调整方式

上面已经说到当树的结构发生改变时,红黑树的条件可能被破坏,需要通过调整使得查找树重新满足红黑树的条件。

调整可以分为两类:一类是颜色调整,即改变某个节点的颜色,这种比较简单,直接将节点颜色进行转换即可;另一类是结构调整,改变检索树的结构关系。结构调整主要包含两个基本操作:左旋(Rotate Left),右旋(RotateRight)。

2.1、左旋

左旋的过程是将 p 的右子树绕 p 逆时针旋转,使得 p 的右子树成为 p 的父亲,同时修改相关节点的引用,使左子树的深度加 1,右子树的深度减 1,通过这种做法来调整树的稳定性。过程如下:
在这里插入图片描述
以 jdk1.8 为例,打开 HashMap 的源码部分,红黑树内部类 TreeNode 属性分析:


static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {//指向父节点的指针TreeNode<K,V> parent;//指向左孩子的指针TreeNode<K,V> left;//指向右孩子的指针TreeNode<K,V> right;//前驱指针,跟next属性相反的指向TreeNode<K,V> prev;//是否为红色节点boolean red;......
}

左旋方法 rotateLeft 如下:


static <K,V> TreeNode<K,V> rotateLeft(TreeNode<K,V> root,TreeNode<K,V> p) {//root:表示根节点//p:表示要调整的节点//r:表示p的右节点//pp:表示p的parent节点//rl:表示p的右孩子的左孩子节点TreeNode<K,V> r, pp, rl;//r判断,如果r为空则旋转没有意义if (p != null && (r = p.right) != null) {//多个等号的连接操作从右往左看,设置rl的父亲为pif ((rl = p.right = r.left) != null)rl.parent = p;//判断p的父亲,为空,为根节点,根节点的话就设置为黑色if ((pp = r.parent = p.parent) == null)(root = r).red = false;//判断p节点是左儿子还是右儿子else if (pp.left == p)pp.left = r;elsepp.right = r;r.left = p;p.parent = r;}return root;

2.2、右旋

了解了左旋转之后,相应的就会有右旋,逻辑基本也是一样,只是方向变了。右旋的过程是将 p 的左子树绕 p 顺时针旋转,使得 p 的左子树成为 p 的父亲,同时修改相关节点的引用,使右子树的深度加 1,左子树的深度减 1,通过这种做法来调整树的稳定性。实现过程如下:
在这里插入图片描述
同样的,右旋方法 rotateRight 如下:

static <K,V> TreeNode<K,V> rotateRight(TreeNode<K,V> root,TreeNode<K,V> p) {//root:表示根节点//p:表示要调整的节点//l:表示p的左节点//pp:表示p的parent节点//lr:表示p的左孩子的右孩子节点TreeNode<K,V> l, pp, lr;//l判断,如果l为空则旋转没有意义if (p != null && (l = p.left) != null) {//多个等号的连接操作从右往左看,设置lr的父亲为pif ((lr = p.left = l.right) != null)lr.parent = p;//判断p的父亲,为空,为根节点,根节点的话就设置为黑色if ((pp = l.parent = p.parent) == null)(root = l).red = false;//判断p节点是右儿子还是左儿子else if (pp.right == p)pp.right = l;elsepp.left = l;l.right = p;p.parent = l;}return root;
}

03、操作示例介绍

3.1、插入调整过程图解

在这里插入图片描述

3.2、删除调整过程图解

在这里插入图片描述

3.3、查询过程图解

在这里插入图片描述

04、总结

至此,红黑树的实现就基本完成了,关于红黑树的结构,有很多种情况,情况也比较复杂,但是整体调整流程,基本都是先调整结构然后调整颜色,直到最后满足红黑树特性要求为止。如果有理解不当之处,欢迎指正!

05、参考资料

1、简书 - JDK1.8红黑树实现分析: https://www.jianshu.com/p/34b6878ae6de

2、知乎 - 史上最清晰的红黑树讲解: https://zhuanlan.zhihu.com/p/24810439?refer=dreawer


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

相关文章

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;所以黑红树出现了。 二、简介…

laravel框架的下载与安装

首先我们先访问这个网址https://github.com/laravel/laravel 可以使用git克隆 或者直接下载安装包到自己的www目录下解压&#xff0c;此时访问localhost下的laravel目录&#xff0c; 此时会报没有vendor文件夹的一个错&#xff0c; 如果你已经下载了composer 在该文件夹目录下…

Laravel

Laravel的安装 1.确认composer已经安装 2.配置homestead.yaml文件sites&#xff1a;- map: laravel.xyz//域名配置to: /home/vagrant/code/laravel/public//入口文件路径 databases&#xff1a;//数据库- laravel 3.用秘钥登录homestead 4.更换中国镜像&#xff1a; composer…

Laravel下载文件及文档

2019独角兽企业重金招聘Python工程师标准>>> Laravel学院提供的相关资源下载 中文文档 Laravel 5.6 中文文档&#xff1a;PDF&#xff08;兼容 5.5 文档&#xff09; Laravel 5.3 中文文档&#xff1a;CHM | PDF Laravel 5.2 中文文档&#xff1a;CHM | PDF Laravel…

Laravel-admin的安装步骤

1、先确保是否安装composer&#xff0c;laravel及其版本并切换到阿里镜像 composer -v 查看composer的版本 php artisan 查看laravel的版本 扩展说明下&#xff1a;如果已经安装好composer&#xff0c;也可以通过 Composer 安装 Laravel 安装器 命令如下&#xff1a;composer…

如何正确的下载安装使用别人的laravel项目?

转载的,写的很简洁明了,白俊瑶博客 laravel 作为最流行的 php 框架&#xff1b;自然少不了很多基于 laravel 开发的项目&#xff1b;不过很多项目因为还处于开发中&#xff1b;或者其他原因并没有写安装文档&#xff1b;举个反面栗子&#xff1b;比如说我的 laravel-bjyadmin ;…

laravel 5.0

1.应用场景 使用PHP5.4[因为php5.4只能最高支持laravel 5.0]快速开发/维护一个web系统 2.学习/操作 1.获取参数 get方式 【查询字符串方式&#xff1a;Query String】 http://test.oa.com/api/u2d/texture/export?nametest&sex男 Route::get(export, U2dTextureControll…

Laravel最新版的安装(图文)

本文只适合刚接触或者想学Laravel的小白&#xff0c;老鸟就自动略过吧。 Laravel是一套简洁、优雅的PHP WEB开发框架&#xff08;PHP Web Framework&#xff09;&#xff0c;具有富于表达性且简洁的语法&#xff0c;Laravel是易于理解且强大的&#xff0c;它提供了强大的工具用…

Laravel 安装

工作需要&#xff0c;得学习一个php的后台admin管理框架&#xff0c;用于管理内容。这一天都在搜GitHub和gitee&#xff0c;GitHub是真的难访问啊&#xff0c;时断时续的&#xff1b;gitee上有一些&#xff0c;但好多都停更了的样子&#xff0c;有一些还不错的&#xff0c;例如…

Laravel 8 文件的上传/下载/显示的实例

如何实现对文件的操作&#xff0c;实现上传&#xff0c;下载&#xff0c;展示等等功能&#xff0c;我们通过编写一个简单的实例来了解其中具体的内容。 文件列表的展示/文件上传/文件下载 首先我们需要创建两个文件&#xff0c;一个视图文件&#xff0c;一个控制器&#xff0c…

安装laravel

安装laravel之前首先应该设置好安装好php&#xff0c;配置好环境变量。之后安装好compser。 1、安装php环境变量。 我使用的php环境安装包是upupw&#xff0c;&#xff08;php环境安装包有很多&#xff0c;例如phpstudy&#xff0c;wamp等等&#xff0c;读者可自行百度。&…