TreeMap - 红黑树
TreeMap是Map家族中的一员,也是用来存放key-value键值对的。平时在工作中使用的可能并不多,它最大的特点是遍历时是有顺序的,根据key的排序规则来
TreeMap是一个双列集合,是Map的子类。底层由红黑树结构构成。
TreeMap是一个基于key有序的key value散列表。
- map根据其键的自然顺序排序,或者根据map创建时提供的Comparator排序
- 不是线程安全的
- key 不可以存入null
- 底层是基于红黑树实现的
特点:
- 元素中键不能重复
- 元素会按照大小顺序排序

以上是TreeMap的类结构图:
- 实现了NavigableMap接口,NavigableMap又实现了Map接口,提供了导航相关的方法。
- 继承了AbstractMap,该方法实现Map操作的骨干逻辑。
- 实现了Cloneable接口,标记该类支持clone方法复制
- 实现了Serializable接口,标记该类支持序列化
package com.hankcs.book.ch02;
import java.util.Map;
import java.util.TreeMap;
public class TreeTest {
public static void main(String[] args) {
Map<Integer, String> treeMap = new TreeMap<>();
treeMap.put(16, "a");
treeMap.put(1, "b");
treeMap.put(4, "c");
treeMap.put(3, "d");
treeMap.put(8, "e");
// 遍历
System.out.println("默认排序:");
treeMap.forEach((key, value) -> {
System.out.println("key: " + key + ", value: " + value);
});
// 构造方法传入比较器
Map<Integer, String> tree2Map = new TreeMap<>((o1, o2) -> o2 - o1);
tree2Map.put(16, "a");
tree2Map.put(1, "b");
tree2Map.put(4, "c");
tree2Map.put(3, "d");
tree2Map.put(8, "e");
// 遍历
System.out.println("倒序排序:");
tree2Map.forEach((key, value) -> {
System.out.println("key: " + key + ", value: " + value);
});
}
}
输出:
默认排序:
key: 1, value: b
key: 3, value: d
key: 4, value: c
key: 8, value: e
key: 16, value: a
倒序排序:
key: 16, value: a
key: 8, value: e
key: 4, value: c
key: 3, value: d
key: 1, value: b
实现原理
了解一下红黑树的特点:红黑树是一颗自平衡的排序二叉树。先从二叉树开始说起。
二叉树

就是每个结点的值按照大小排列的二叉树,二叉查找树方便对结点的值进行查找
特点
- 节点的左子树小于节点本身;
- 节点的右子树大于节点本身;
- 左右子树同样为二叉搜索树;
- 没有相等的结点;
二叉查找树的查找操作
查找方式:
从根结点开始,如果要查找的数据等于结点的值, 那就返回。
如果要查找的数据小于结点的值,那就在左子树中递归查找;
如果要查找的数据大于结点的值,那就在右子树中递归查找。
红黑树

它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目
特点
- 每个节点都只能是红色或者黑色;
- 根节点必为黑色;
- 每个叶节点(NIL节点,空节点)是黑色的。
- 连接红色节点的两个子节点都为黑色(红黑树不会出现相邻的红色节点);
- 从任意节点出发,到其每个叶子节点的路径中包含相同数量的黑色节点;
- 新加入到红黑树的节点为红色节点;
红黑树自平衡基本操作:
- 变色:在不违反上述红黑树规则特点情况下,将红黑树某个node节点颜色由红变黑,或者由黑变红;
- 左旋:逆时针旋转两个节点,让一个节点被其右子节点取代,而该节点成为右子节点的左子节点
- 右旋:顺时针旋转两个节点,让一个节点被其左子节点取代,而该节点成为左子节点的右子节点
红黑树的好处主要包括:
- 插入、删除和查找的时间复杂度最坏情况下为O(log n),使得红黑树在时间敏感的应用如即时应用(real time application)中具有价值,同时也可以作为其他提供最坏情况担保的数据结构中的构建板块,例如,在计算几何中使用的很多数据结构都可以基于红黑树。
- 红黑树在函数式编程中也特别有用,是最常用的持久数据结构之一,它们用来构造关联数组和集合,在突变之后它们能保持为以前的版本。
- 红黑树是2-3-4树的一种等同,对于每个2-3-4树,都存在至少一个数据元素是同样次序的红黑树。在2-3-4树上的插入和删除操作也等同于在红黑树中颜色翻转和旋转。
- 与AVL树相比,红黑树在插入和删除时不需要维护绝对的平衡,旋转次数减少,可以提高效率。同时红黑树的平均查找效率还是log2(n)。
总之,红黑树具有较高的查找效率、插入和删除效率,同时对空间的使用效率也较高。
https://www.cnblogs.com/LiaHon/p/11203229.html
TreeMap - 红黑树的更多相关文章
- 通过分析 JDK 源代码研究 TreeMap 红黑树算法实现
本文转载自http://www.ibm.com/developerworks/cn/java/j-lo-tree/ 目录: TreeSet 和 TreeMap 的关系 TreeMap 的添加节点 Tr ...
- 研究jdk关于TreeMap 红黑树算法实现
因为TreeMap的实现方式是用红黑树这种数据结构进行存储的,所以呢我主要通过分析红黑树的实现在看待TreeMap,侧重点也在于如何实现红黑树,因为网上已经有非常都的关于红黑树的实现.我也看了些,但是 ...
- 通过分析 JDK 源代码研究 TreeMap 红黑树算法实现--转
TreeMap 和 TreeSet 是 Java Collection Framework 的两个重要成员,其中 TreeMap 是 Map 接口的常用实现类,而 TreeSet 是 Set 接口的常 ...
- TreeMap 红黑树实现
TreeMap 是一个有序的key-value集合,它是通过 红黑树 实现的. TreeMap 继承于AbstractMap,所以它是一个Map,即一个key-value集合. TreeMap 实现了 ...
- 通过分析 JDK 源代码研究 TreeMap 红黑树算法实
TreeMap和TreeSet是Java Collection Framework的两个重要成员,其中TreeMap是Map接口的常用实现类,而TreeSet是Set接口的常用实现类.虽然HashMa ...
- TreeMap红黑树
Java TreeMap实现了SortedMap接口,也就是说会按照key的大小顺序对Map中的元素进行排序,key大小的评判可以通过其本身的自然顺序(natural ordering),也可以通过构 ...
- 53 容器(八)——TreeMap 红黑树
红黑树是比较难以理解的一种数据结构.它能从10亿数据中进行10几次比较就能查找到需要的数据.效率非常高. 理解起内部结构也难. 现阶段我们知道有这种东西就行了. 参考文章: https://www.j ...
- 红黑树、TreeMap、TreeSet
事先声明以下代码基于JDK1.8版本 参考资料 大部分图片引自https://www.jianshu.com/p/e136ec79235c侵删 https://www.cnblogs.com/skyw ...
- 【深入理解Java集合框架】红黑树讲解(上)
来源:史上最清晰的红黑树讲解(上) - CarpenterLee 作者:CarpenterLee(转载已获得作者许可,如需转载请与原作者联系) 文中所有图片点击之后均可查看大图! 史上最清晰的红黑树讲 ...
- 大数据学习--day17(Map--HashMap--TreeMap、红黑树)
Map--HashMap--TreeMap--红黑树 Map:三种遍历方式 HashMap:拉链法.用哈希函数计算出int值. 用桶的思想去存储元素.桶里的元素用链表串起来,之后长了的话转红黑树. T ...
随机推荐
- Altium Designer中'=SheetNumber'和'=SheetTotal'参数无效的解决方法
出现的问题 图纸没有被自动编号 在Altium中该显示区域被称为Title Block.[这里使用了图纸模板]. 当使用层次化的设计方式时,往往一个工程中若干幅原理图.这时我们需要为原理图进行编号. ...
- WPF --- 如何以Binding方式隐藏DataGrid列
引言 如题,如何以Binding的方式动态隐藏DataGrid列? 预想方案 像这样: 先在ViewModel创建数据源 People 和控制列隐藏的 IsVisibility,这里直接以 MainW ...
- 【uniapp】【微信小程序】【外包杯】如何创建分包
意义:分包可以减少小程序数次启动时的加载时间 1.创建分包的根目录 2.在page.json中,和pages节点平级的位置声明节点,用来定义分包的相关结构 3.在subpkg目录上新建页面 4.完成了
- 使用halo快速搭建应用文档中心
背景 之前我写了一篇,用gitbook搭建文档中心,gitbook是一款搭建博客的技术,是静态博客技术,不带后台管理系统.不带数据库,要发文章的话,是通过提供markdown文件,渲染成html,通过 ...
- Android12版本闹钟服务崩溃问题
原文地址: Android12版本闹钟服务崩溃问题 - Stars-One的杂货小窝 公司项目app线上出现的崩溃记录问题,崩溃日志如下所示: Caused by java.lang.Security ...
- 前端传递Base64字符串,后端转流存入OSS
工具类 public static BufferedInputStream base64Convert(String base64) { // 解码 base64 = base64.split(&qu ...
- Java中获取Class对象的三种方式
在Java中,我们经常需要获取某个类的Class对象,以便进行反射操作.动态加载类或者获取类的信息.本文将介绍Java中获取Class对象的三种常见方式. 1. 使用.class语法 获取Class对 ...
- jclasslib的安装
双击安装包打开后点击下一步,然后选择安装的路径. 默认路径,如果c盘有空间不建议更改路径,然后再次点击下一步 依然选择下一步 最后点击完成即可完成安装.现在可以使用啦 注:如果需要安装包,请点击下面链 ...
- DDD落地实践-架构师眼中的餐厅 | 京东云技术团队
本文以餐厅场景为叙事主线,以领域驱动为核心思想,结合架构设计与功能设计方法论.是从领域分析到落地的全过程案例,内容偏重于落地,因此不乏一些探讨,欢迎指正. 文章较长.全程干货.耐心读完.必有收获. 本 ...
- ubuntu upgrade problem
出现问题: W: Failed to fetch bzip2:/var/lib/apt/lists/partial/ppa.launchpad.net_webupd8team_java_ubuntu_ ...