0

0

详解HashMap的TreeNode类结构_红黑树节点与双向链表节点的复合

P粉602998670

P粉602998670

发布时间:2026-02-18 10:12:54

|

809人浏览过

|

来源于php中文网

原创

treenode既是红黑树节点又是链表节点,因其继承linkedhashmap.entry(含before/after)且源自node(含prev/next),分别支持树结构(left/right/parent/red)和哈希桶内链表连接(prev/next)。

详解hashmap的treenode类结构_红黑树节点与双向链表节点的复合

TreeNode为什么既是红黑树节点又是链表节点

因为 TreeNode 继承自 LinkedHashMap.Entry,而后者本身就有 beforeafter 字段——这是双向链表的前驱/后继指针。所以它天然支持两种结构:作为红黑树节点时用 left/right/parent/red;作为插入顺序链表节点时用 prev/next(注意:不是 before/afterprev/next 来自 Node 的继承,用于哈希桶内链表连接)。

常见错误现象:NullPointerException 出现在遍历 TreeNodeprevnext 时,其实是误把树节点当普通链表节点直接遍历,忽略了它只在「树化后仍需维持原桶内顺序」时才有效连接。

  • prevnext 仅在该 TreeNode 被挂载到哈希桶数组中时被维护(比如调用 moveRootToFront 后),不是树结构的一部分
  • 树内遍历必须走 left/right,不能靠 next 遍历整棵树
  • 反树化(untreeify)时会用 prev/next 快速重建链表,但此时 left/right 已失效

treeify() 怎么把链表转成红黑树

核心是两步:先构造一棵普通的二叉搜索树(BST),再通过 balanceInsertion 逐个染色+旋转,恢复红黑性质。整个过程不改变原有 Nodehash/key/value,只是把它们包装成 TreeNode 并重连指针。

使用场景:当某个桶中 Node 链表长度 ≥ 8 且哈希表容量 ≥ 64 时触发,否则只扩容不树化。

  • 树化前会尝试用 comparableClassFor + compareComparables 获取 key 的自然序;失败则 fallback 到 tieBreakOrder(基于 System.identityHashCode 和类名哈希)保证可比性
  • 所有新创建的 TreeNode 默认为红色,插入后统一由 balanceInsertion 调整
  • 注意:树化不是“复制数据”,而是原地升级节点类型——原来的 Node 对象被强转为 TreeNode,其 next 字段仍保留,用于维持桶内链表结构

removeTreeNode() 删除时最常踩的三个坑

删除操作远比插入复杂,因为要同时维护红黑树平衡和哈希桶链表结构,稍有不慎就断链或失衡。

笔头写作
笔头写作

AI为论文写作赋能,协助你从0到1。

下载

常见错误现象:删除后 get() 返回 null、size() 不对、甚至 ConcurrentModificationException(多线程下未同步)。

  • 没调用 unmap 或漏掉 root 重连逻辑,导致该桶的 tab[index] 指向一个已从树中摘除但未从桶链表中移出的节点
  • 删除后未调用 balanceDeletion,红黑树黑高失衡,后续查找可能漏节点(尤其在左/右子树黑高不等时)
  • 反树化阈值判断写错:JDK 规定树中节点 ≤ 6 才 untreeify,但有人误用“桶中总节点数 ≤ 6”,忽略当前已是树结构的事实

TreeNode 的 color 字段为什么是布尔型而不是枚举

因为 red 字段定义为 boolean red,不是 Color.RED/BLACK。这是纯粹的性能取舍:避免对象创建和虚方法分派,用单 bit 存储更省内存、更快访问。

性能影响:在高频插入/删除路径(如 putValremoveNode)中,每次颜色判断都是 if (p.red) 这种直接位读取,比 if (p.color == Color.RED) 少一次字段解引用和常量比较。

  • 所有红黑树操作(rotateLeftrotateRightbalanceInsertion)都基于这个布尔值做分支,没有抽象层
  • 别试图给 TreeNode 加 color getter/setter——它压根没提供,直接读写 red 字段是唯一正解
  • 调试时打印 TreeNode 看不到 color?那是 toString() 没输出它,得手动打 p.red ? "RED" : "BLACK"

真正麻烦的从来不是“怎么写 TreeNode”,而是搞清它在哪一刻属于树、在哪一刻属于链表、又在哪一刻两者都得保——这三个身份切换全靠几行指针赋值,手抖一下,prev 指向了 right,或者 root 没挪到桶头,问题就藏进去了。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java中boolean的用法
java中boolean的用法

在Java中,boolean是一种基本数据类型,它只有两个可能的值:true和false。boolean类型经常用于条件测试,比如进行比较或者检查某个条件是否满足。想了解更多java中boolean的相关内容,可以阅读本专题下面的文章。

362

2023.11.13

java boolean类型
java boolean类型

本专题整合了java中boolean类型相关教程,阅读专题下面的文章了解更多详细内容。

37

2025.11.30

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

244

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

766

2024.03.01

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1553

2023.10.24

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

817

2023.08.22

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

817

2023.08.22

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

675

2023.08.10

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

561

2026.02.13

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
HTML5/CSS3/JavaScript/ES6入门课程
HTML5/CSS3/JavaScript/ES6入门课程

共102课时 | 7.1万人学习

前端基础到实战(HTML5+CSS3+ES6+NPM)
前端基础到实战(HTML5+CSS3+ES6+NPM)

共162课时 | 20.2万人学习

第二十二期_前端开发
第二十二期_前端开发

共119课时 | 13万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号