TreeMap是一种通过实现了红黑树数据结构的Map集合。

【图片有英文注释的均摘抄于国外文章】

首先,先来看一些基础概念。

1. 二叉排序树

二叉排序树的定义和性质:

(1)若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值;

(2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;

(3)左、右子树也分别为二叉排序树;

【摘自百度百科】

.

如下图是一个普通的二叉树结构:

二叉树【摘抄于国外文章】

上图是相应的根据值比较生成的一个简单的二叉树,那么对应查找就非常简单,不断通过比较节点的值,大于就向右子树走,小于就往左子树走,相同则返回当前值.

二叉树查找【摘抄于国外文章】

对应插入就可以类似查找,先查到当前值于节点比较,如果找到,直接更新,没有找到就不断往子节点寻找,直到到达为空的子节点,将值填入到该空节点上。

二叉树插入【摘抄于国外文章】

二叉树查找的时候,查找的效率和树的形状有关,当节点完全平衡时(最底层子节点到根节点的“路程”相同),效率最高;当所有节点都只有一个子节点时,效率最差

二叉树效率【摘抄于国外文章】

2. B树

B-树是一种多路搜索树(并不一定是二叉的)

如下图,节点内有多个值(多路):

B树【摘抄于国外文章】

上图展示的最多只有两个三个子节点的B树,这种简单结构的树可以称为2-3树,这里点到为止,后续将通过这种树去分析后续的红黑树

3. 2-3树

2-3树允许每个节点保存1个或2个值,含有1个值节点称为2-node(有两个子节点),含有2个值的节点称为3-node(有三个子节点)。

如图:

2-3树【摘抄于国外文章】

在2-3树中查找,与二叉树类似,通过不断和节点比较进行向下查找,需要注意的是,在3-node节点中,需要同时比较两个值,如果介于两个值之间,需要找的子节点就是中间的子节点。

2-3树查找过程【摘抄于国外文章】

这里重点讨论一下插入操作,首先看一种简单的,往2-node节点插入;如果找到的末节点是一个2-node的节点,直接在此节点上新增当前值,将其节点变成3-node节点,如图:

2-3树2-node新增【摘抄于国外文章】

当插入的节点是3-node节点时,应该怎么操作?首先看一下一个最简单的,只有一个3-node节点的树:

2-3树3-node根新增【摘抄于国外文章】

首先,将值插入到当前的3-node节点,将其变成4-node节点,然后提取中间的值,让其分解为一个普通的二叉树即可。

那么如果当前插入的3-node节点有父节点时应该怎么处理呢,首先还是将3-node变成4-node节点,然后拆解出一个父节点插入到原来的父节点中,如果当前父节点是2-node节点,那么将其变成3-node节点,如果原来父节点已经是3-node节点,那么循环上面的处理步骤。

2-3树3-node根新增【摘抄于国外文章】

2-3树3-node根新增【摘抄于国外文章】

总结一下步骤:

查找需要插入值的位置

判断当前插入节点是否是2-node节点,如果是,则将其变成3-node节点,如不是,继续执行一下步骤

将当前节点变成4-node节点

4.分解当前4-node节点,判断当前节点是否为根节点,如果是,将整个2-3树,提高一层,如不是,继续执行一下步骤

新增的上层节点插入到父节点中,重复执行2-4步,直到结束

4. 红黑树

红黑树是一种解决平衡二叉树的方法。红黑树具有以下性质:

节点是红色或黑色。

根节点是黑色。

每个叶节点(NIL节点,空节点)是黑色的。

每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)

5.从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

【摘自百度百科】

红黑树【摘抄于国外文章】

红黑树其实是2-3树的一种二叉树表现方法,如果将红线连接线水平连接,那么连接的两个节点就是2-3树中的3-node节点,其他没有红线连接的就是2-3树中的2-node节点,如图:

红黑树与2-3树【摘抄于国外文章】

在讲解插入操作前,先了解集中红黑树的平衡操作。第一种是左旋转和右旋转:

左旋转【摘抄于国外文章】

右旋转【摘抄于国外文章】

第二种是颜色反转,当出现一个节点下的两个节点均是红色时,可以转换到2-3树中思考,这是一个4-node节点,那么需要将其分解为一个二叉树,并向上合并:

颜色转换【摘抄于国外文章】

有了2-3树的插入讲解,这边,直接分析最复杂的红黑树插入:

红黑树插入【摘抄于国外文章】

查找需要插入值的位置

新插入的节点元素用红色标识(2-3树中插入到2-node节点,将其变成3-node节点)

如果出现节点下的两个子节点都是红色时(4-node节点),需要进行颜色转换(或旋转)

选取红黑树比完全平衡二叉树的好处就是,红黑树是一种代价较小就可以实现较平衡的二叉树的结构,最差的情况也就是比完全二叉树的深度多一倍,但是在删除操作的平衡里面可以节省很多的效率。

5. TreeMap

通过分析二叉树和红黑树的概念,再来看源码,首先看TreeMap的容器:

private transient Entry root = null;

其中,TreeMap重写了Entry类:

K key;

V value;

Entry left = null;

Entry right = null;

Entry parent;

其中key value是为了实现Map的键值结构,left、right、parent表示的是二叉树中一个节点与其他节点的关系指针。

TreeMap提供了节点值比较的接口:

private final Comparator super K> comparator;

接下来,看一下put方法:

public V put(K key, V value) {

Entry t = root;

... ...

int cmp;

Entry parent;

// split comparator and comparable paths

Comparator 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;

else

return t.setValue(value);

} while (t != null);

}

... ...

fixAfterInsertion(e);

... ...

}

首先获取当前的比较器,运用当前比较器作为后续比较的工具(比较器为空则用默认的,默认的逻辑和有比较器的类似,不重复分析).然后小于,则跳到左边的节点继续比较,如果大于则在右边子节点比较,如果相同,则设置当前值。然后调用fixAfterInsertion平衡红黑树操作。

先偷一下懒,里面的平衡源码就不分析了。

java map 红黑树_Java集合-TreeMap和红黑树相关推荐

  1. 红黑树 键值_Java集合框架:红黑树概念、插入及旋转操作详细解读就问你会不会...

    初识TreeMap 之前的文章讲解了两种Map,分别是HashMap与LinkedHashMap,它们保证了以O(1)的时间复杂度进行增.删.改.查,从存储角度考虑,这两种数据结构是非常优秀的.另外, ...

  2. java list取值_Java集合详解

    一.集合的由来 通常,我们的程序需要根据程序运行时才知道创建多少个对象.但若非程序运行,程序开发阶段,我们根本不知道到底需要多少个数量的对象,甚至不知道它的准确类型.为了满足这些常规的编程需要,我们要 ...

  3. java的set接口_Java集合-Set接口

    importorg.junit.Test;import java.util.*;/*** * Collection接口:单列集合,用来存储一个一个的对象 * (不常用)子接口Set:存储无序的.不可重 ...

  4. java map 元素个数_Java 小模块之--统计字符串中元素个数

    Java 小模块之--统计字符串中元素个数 曾经看过我Stream或者Guava类库等文章的小伙伴应该很明白我这篇博文的意义所在了 一是给读者提供综合的博文入口 二是自己也总结一下思路 ps: 之前没 ...

  5. java hashset 源码_Java集合源码分析-HashSet和LinkedHashSet

    前两篇文章分别分析了Java的ArrayList和LinkedList实现原理,这篇文章分析下HashSet和LinkedHashSet的源码.重点讲解HashSet,因为LinkedHashSet是 ...

  6. java map key 升序_Java Map 按 key 升序排序

    最近开发微信和支付宝的服务端支付,涉及到字典的排序和 url 参数转换成字典的操作,整理了一个工具类: import java.util.ArrayList; import java.util.Col ...

  7. java map 面试题_Java 面试系列:集合详解之 Map + 面试题

    集合有两个大接口:Collection 和 Map,本文重点来讲解集合中另一个常用的集合类型 Map. 以下是 Map 的继承关系图: avatar Map 简介 Map 常用的实现类如下: Hash ...

  8. java地图源码_Java集合源码分析(四)HashMap

    一.HashMap简介 1.1.HashMap概述 HashMap是基于哈希表的Map接口实现的,它存储的是内容是键值对映射.此类不保证映射的顺序,假定哈希函数将元素适当的分布在各桶之间,可为基本操作 ...

  9. java map取值_Java Set接口 Map 与枚举

    Set接口 概述 一个不包含重复元素的 collection.更确切地讲,set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素 特点 Set接口是 ...

最新文章

  1. TorchVision中通过AlexNet网络进行图像分类
  2. 如何及时获得AI顶尖科研团队的最新论文与进展?只需一份AI内参!
  3. spring_了解Spring Web应用程序体系结构:经典方法
  4. java中动态代理实现机制
  5. Qt Creator优化移动设备的应用程序
  6. Emacs-小白入坑之旅
  7. 【数学模型】基于Matlab模拟超市排队系统
  8. html高难度拼图,张馨月婚后生活太悠闲,宅家挑战高难度拼图
  9. 从360首席科学家到区块链创业者,苦钻代码、强迫自己看白皮书,原来这个圈子都是这么努力的 | 人物志...
  10. 计算机应用基础excel2007 6.2使用函数和公式 教案,计算机应用基础教案6.2使用函数和公式.docx...
  11. 要把服务器架在太空的海盗湾,为什么能活十五年?
  12. 基于模型的设计及其嵌入式实现(无水印).pdf_DeepMind打造最强表示学习模型BigBiGAN,Goodfellow点赞!...
  13. 联想电脑 恢复键盘F1-F12按键的标准功能
  14. 为什么选择MVVM而不是MVP - Android体系结构
  15. 为什么应该为“数据时代原住民”打造智能产品?
  16. opencv学习笔记(八)-- 在图像上绘制形状和文字
  17. vins安装及小觅深度版运行
  18. 当年的Windows98
  19. Java的jar包打包成exe应用
  20. 雷达编程实战之恒虚警率(CFAR)检测

热门文章

  1. clickhouse 新增列_ClickHouse入门记录
  2. 通过学历造假获得面试机会,并成功拿到 Offer,这样的操作你认可吗?
  3. 被政治割裂的开源:伊朗开源拒绝来自以色列的PR
  4. 一上来,就问原理,问上亿(MySQL)大表的索引优化...
  5. Spring Boot + Redis 实现接口幂等性 | 分布式开发必知!
  6. 深入Java中的位操作
  7. Spring Cloud中Hystrix 线程隔离导致ThreadLocal数据丢失(续)
  8. 坐标系转换公式_【技术】西安80坐标与地方坐标系的转换方法技巧
  9. 电脑版java运行条件,Java Runtime Environment电脑版-Java Runtime Environment(Java运行环境)8.0.221 x64正式版-蜻蜓手游网...
  10. mysql账号管理系统_简单账号管理系统的实现(b/s、servlet、html、mysql)