HashMap之节点删除

  大家一直关注的都是HashMap如何添加节点,当节点数量大于8的时候转化为红黑树,否则使用链表等等,但大家是否有看过删除节点的处理逻辑呢? 今天来看看HashMap删除节点的神来之笔

问题来源

  在查看HashMap源码时,有个以下字段,在删除的时候,判断节点数量,最多在小于6的时候,会untreeifying(树转化为链表),在点击这个字段时发现,只有在split()方法中使用,但split()方法在resize()方法中使用,与删除节点无关,遂去翻删除节点的代码逻辑

  

节点删除

  通过remove方法,一路进来,找到删除节点的地方。如下图:

   

我们进入removeTreeNode方法中,代码如下:

  

查看方法注释,里面介绍到:如果节点太少,就会把当前bin转换成普通bin。不理解注释没关系,我们进入这个方法中唯一有转化的地方。进入untreeify()方法查看下。代码如下:

  

噢,第一行看一下,if,else看一下,嗯,这个方法就是获取返回了一个列表(这些方法都是TreeNode类里面的方法,所以请注意,this就是当前要操作的TreeNode节点)。到此明白,这个方法就是把红黑树转化成链表的,那么我的就得分析分析是如何操作的了,而没有使用到定义的全局变量。

删除判断逻辑分析

  

  我们来分析分析上面这个逻辑,进入这个untreeify() 的要求是,root == null, root.right ==null, root.left==null, root.left.left==null四种情况,我们以7个节点的红黑树来分析,A为root节点。

  

  所以进入这个方法主要有以下几种情况,我们一种一种的来分析当满足要求时,节点的个数。(这里默认认为知道红黑树的5个特点,主要是黑平衡)

  当这四种情况都满足时,我们可以看出最多节点有如上图所示个数,可以为7个。(大于8个不考虑,因为大于8会变成红黑树)。

    1.  最多节点情况:当我们删除节点D时,只满足root.left.left==null这个条件,这棵树仍可以维持红黑树的特点,这时的最大节点数为6.

    2.  最少节点情况:当EFG不存在时,在A,B,C,D中删除任意一个节点,都会满足上述四种规则中的一种。则存在最少节点情况,有3个节点。

  以上情况都是会将树转化成链表,此时的节点是 3<= nodes <=6 ,由此可以看出,当节点数在小于6时,是可能转化成链表,但不是绝对情况, 所以使用定义的变量(固定数量6)也不正确。只好通过判断去动态获取节点数。

节点数量原因分析  

  为什么在小于6的时候可能转换成链表,而在大于8的时候转化成红黑树?

    主要通过时间查询节点分析,红黑树的平均查询时间为 log(n), 而链表是O(n),平均是O(n)/2。

    当节点数为8时,红黑树查询时间3,链表查询时间是4, 可以看出来当红黑树查询效率大于了链表。(两个函数曲线问题,当节点更多是,比红黑树需要的时间更多)

    当节点数为6时,为什么转换成链表,我认为主要时因为节点数太少,如果还是用红黑树,为了维持红黑树的特点,则需要翻转,左旋,右旋,等,更消耗性能。

  为什么不是7是转化?

    主要是为了给一个过渡,防止频繁转化。 也如上图,7个节点可能正好是一个满二叉树。

HashMap1.8之节点删除分析的更多相关文章

  1. 转载-HashMap1.8源码分析

    原文地址-https://tech.meituan.com/2016/06/24/java-hashmap.html HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型.随着 ...

  2. 转载-HashMap1.7源码分析

    原文地址-https://www.cnblogs.com/chengxiao/p/6059914.html HashMap实现原理及源码分析   哈希表(hash table)也叫散列表,是一种非常重 ...

  3. HashMap1.8源码分析(红黑树)

    转载:https://segmentfault.com/a/1190000012926722?utm_source=tag-newest https://blog.csdn.net/weixin_40 ...

  4. Java 集合系列之五:Map基本操作

    1. Java Map 1. Java Map 重要观点 Java Map接口是Java Collections Framework的成员.但是它不是Collection 将键映射到值的对象.一个映射 ...

  5. java容器源码分析及常见面试题笔记

      概览 容器主要包括 Collection 和 Map 两种,Collection 存储着对象的集合,而 Map 存储着键值对(两个对象)的映射表. List Arraylist: Object数组 ...

  6. JDK1.8 HashMap 源码分析

    一.概述 以键值对的形式存储,是基于Map接口的实现,可以接收null的键值,不保证有序(比如插入顺序),存储着Entry(hash, key, value, next)对象. 二.示例 public ...

  7. Device Tree(三):代码分析【转】

    转自:http://www.wowotech.net/linux_kenrel/dt-code-analysis.html Device Tree(三):代码分析 作者:linuxer 发布于:201 ...

  8. 数据结构之链表C语言实现以及使用场景分析

    牢骚:本篇博客两个星期前已经存为草稿,鉴于发生一些糟糕的事情,今天才基本完成.本人6月份应届毕业生一枚,毕业后当天来到帝都,之后也非常顺利,面试了俩家公司都成功了.一家做C++方面电商ERP,一家做w ...

  9. lightning mdb 源代码分析系列(3)

    本系列前两章已经描述了系统架构以及系统构建的基础内存映射,本章将详细描述lmdb的核心,外存B+Tree的操作.本文将从基本原理.内存操作方式.外存操作方式以及LMDB中的相关函数等几方面描述LMDB ...

随机推荐

  1. python中os.path.abspath与os.path.realpath 区别

    python中os.path.abspath与os.path.realpath 区别cd /homemkdir amkdir btouch a/1.txtln -s /home/a/1.txt /ho ...

  2. 基于soa的架构

    SOA:Service Oriented Architecture面向服务的架构.也就是把工程拆分成服务层.表现层两个工程.服务层中包含业务逻辑,只需要对外提供服务即可.表现层只需要处理和页面的交互, ...

  3. HDU2612 Find a way (跑两遍BFS)

    Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Ningbo one year ...

  4. TomcatJVM参数优化降低内存使用率(重点)!

    JVM是jdk最底层的支柱 做JVM参数优化主要是为了改善服务器性能以及内存使用率 JAVA堆分为三大部分:(新生代.老年代.永久代) ================================ ...

  5. 「JSOI2014」矩形并

    「JSOI2014」矩形并 传送门 我们首先考虑怎么算这个期望比较好. 我们不难发现每一个矩形要和 \(n - 1\) 个矩形去交,而总共又有 \(n\) 个矩形,所以我们把矩形两两之间的交全部加起来 ...

  6. [PHP]PHP中申明 declare(strict_types=1)的作用

    strict_types=1 针对参数类型开启严格模式,进行数据类型检验,默认是弱类型校验哪个文件写了declare,哪个文件中的所有代码就需要检查 declare(strict_types=1); ...

  7. JavaScript - Array对象,数组

    1. 创建数组 方式1. new关键字 var arr = new Array(1, 2, 3); 方式2. 使用字面量创建数组对象 var arr = [1, 2, 3]; 2. 检测一个对象是否是 ...

  8. SSH整合hibernate无法正常自动生成表

    检查持久化类的属性和映射文件是否正确配置,比如date格式的属性最容易配置错误

  9. 吴裕雄--天生自然PythonDjangoWeb企业开发:解决Pythonno module named "XX"问题

    在项目中加入 sys.path.append('你的django项目路径') sys.path.append('python的site-packages路径')

  10. Kali中文乱码问题

    上面的是用网上介绍的安装组件无法安装,老是提示最后一句:Unable to locate package ...... 后来觉得应该是因为安装Kali时在最后有个选择更新系统的一个配置上,我选择了下面 ...