JDK 源码中怎么分析 TreeMap 的红黑树自平衡调整过程

胖涛吖_9458

胖涛吖_9458

2026-08-09

860人浏览

原创

TreeMap的put()插入红色节点后调用fixAfterInsertion()处理红-红冲突,分三种情形:叔父为红则变色并上移;LL型右旋加变色;LR型先左旋转LL再处理,最终根节点染黑以满足红黑树五性质。

jdk 源码中怎么分析 treemap 的红黑树自平衡调整过程

直接看 TreeMap 的 put() 方法入口,关键逻辑在插入后调用的 fixAfterInsertion() —— 这是整个自平衡调整的核心,所有旋转和变色都发生在这里。

定位核心方法:从 put 到 fixAfterInsertion

插入新节点时,put() 先按二叉搜索树规则找到叶子位置,新建红色节点挂载,然后立即调用 fixAfterInsertion(Entry x)。这个方法接收刚插入的节点(标记为 x),只在满足三个条件时才真正进入调整逻辑:
• x != null
• x != root
• x.parent.color == RED
不满足任一条件就跳过调整——说明当前结构仍符合红黑树五条性质。

理解调整逻辑的三类场景

fixAfterInsertion 本质是处理「红-红冲突」,即父节点为红,违反性质4(红节点子节点必须为黑)。它通过判断 x 相对于祖父节点 g 的位置关系,分三种情况处理:

  • 情形1:叔父节点 y 是红色 → 简单变色:把父节点 p 和叔父 y 染黑,祖父 g 染红;再将 x 上移到 g,继续向上检查
  • 情形2:x 是父节点的左孩子,父节点是祖父的左孩子(LL) → 右旋 + 变色:先对祖父 g 右旋,再交换 p 和 g 颜色
  • 情形3:x 是父节点的右孩子,父节点是祖父的左孩子(LR) → 先左旋父节点,再按情形2处理:即先对 p 左旋使结构转为 LL,再对新祖父右旋并变色

这三类覆盖了所有可能的红-红路径,JDK 实现中用 if-else if-else 分支明确区分左右子树方向,并复用 rotateLeft() 和 rotateRight() 方法完成物理结构调整。

javascript-typescript-typescript-scaffold
javascript-typescript-typescript-scaffold

你是 TypeScript 项目架构专家,专注于脚手架搭建生产就绪的 Node.js 和前端应用。生成包含现代工具链(pnpm、Vite、Next.js)、类型

下载

注意颜色定义与边界细节

源码中用布尔值表示颜色:static final boolean BLACK = true,RED = false。这意味着所有新节点默认构造为 color = BLACK,但 put() 中显式设为红色:e.color = RED。根节点最终强制染黑——这是在 fixAfterInsertion 结束后、或插入完成时由逻辑保证的(例如当 x 上移至根,循环退出后会单独执行 root.color = BLACK)。

验证是否平衡:对照五条红黑树性质

每次调整后,可手动核对是否仍满足全部五条性质:
• 节点非红即黑
• 根为黑
• 所有叶子(null)视为黑节点
• 红节点子节点全为黑
• 任意节点到各叶子的黑节点数相等(黑高不变)
其中第5条最难直观验证,但 JDK 的实现确保:变色不改变黑高,单/双旋也不改变各路径黑节点数量——这是红黑树能维持 O(log n) 性能的根本保障。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

java

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

2025.09.05

730

5

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

2025.11.16

343

7

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

2025.11.17

553

20

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

2025.11.27

323

6

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

2026.11.12

20

15

Go-Zero安装与goctl环境配置教程
Go-Zero安装与goctl环境配置教程

本专题围绕Go-Zero的安装与工具链配置展开,讲清Go版本要求、goctl安装方式、代理镜像、protoc依赖与环境变量设置,说明多版本共存、升级回退与CI流水线安装的做法,并整理安装阶段的常见报错与验证步骤。

2026.11.12

0

15

Go-Zero零基础入门教程
Go-Zero零基础入门教程

本专题整理Go-Zero的入门知识,从框架定位、环境准备到跑通第一个API服务,讲清目录分层、配置加载、日志与中间件的基本用法,并对比Gin、Kratos的差异,帮助Go开发者建立整体认知,判断它是否适合当前项目。

2026.11.12

20

15

Postman身份认证怎么配置
Postman身份认证怎么配置

本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

2026.11.06

120

12

Postman请求头Headers怎么设置
Postman请求头Headers怎么设置

围绕Postman HTTP请求头配置展开,讲解Headers选项的具体使用方式,包括Key和Value参数填写、请求头信息添加、常见Header字段设置及请求头修改方法,帮助用户解决接口调试过程中遇到的请求头配置问题。

2026.11.06

100

13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习