时间: 2021年10月19日星期二 阴
1. 题目
大家好,我是小崔爱读书,本期要说的是《2020年Java面试208题》的第20题。
面试官问了这样一个问题: 请说说 TreeMap的底层原理。
2. 知识点分析
TreeMap是基于红黑树的Map,因此这个题目要讲解一下红黑树。
要说红黑树呢,又得讲二叉树,二叉查找树,这说起来话就长了,咱闲言少叙就从头说起吧。
2.1. 为什么要用树
在计算机里面的树是一种数据结构,我觉得最简单的数据结构应该是数组,树也是一种数据结构。
数据结构是干什么的?俩目的:1 存储数据;2 查找数据;
设计数据结构的目的就是为了方便的存储数据,再方便快速的查找读取数据。
数组可以很方便和快速的存储数据,但查找数据就很不好用了,因为数组需要遍历,越是大的数组查找的速度就越慢,这个复杂度是 O(n) 。
因此,数学家们就想办法找到更优秀的数据存储方式,以方便快速查找数据。树就是一种优秀的数据结构。
树的形式其实是复杂的链表,链表的前后都只有1个节点,而树的每个节点可以分叉,下方可以有多个节点,由于有多个节点,分叉了,就形成树了。
如果我们让树上的下级节点都只有一个,那么就是一个链表,而不是树了。
2.2. 二叉树
咱们先从二叉树谈起。二叉树是最简单的一种树。就是每个节点下最多只能有两个节点,这样就形成二叉树了。
注意一下,这个二叉树就是一个随便排列的树形结构,其实没啥用。
2.3. 二叉查找树
二叉查找树就非常有用了,这种二叉树的规则就要求不能随便乱放节点了,而是要求左侧的 节点必须都比根节点小,右侧的所有节点必须都比根节点大。
基于这种规则排列的二叉树,要想查找一个节点速度就很快了,只要比较目标节点与根节点的大小,就知道目标节点在左边还是在右边,这样一级级的找下去,很快就能找到目标节点了。
不过二叉查找树还有一个问题,就是如果摆放的不太好,形成了的二叉树不平衡的问题就麻烦了,比如,根节点是10,左边就一个节点5,右侧顺序是 11,12, 13, 14,15 几个节点组成了一个很长的单链,类似这样不平衡的树,查找起来就完全达不到高效的目的,简直就跟直接使用链表差不多了。
2.4. 红黑树
红黑树的设计目标就是为了实现平衡的二叉查找树。
红黑树本质也是二叉查找树,因此有二叉查找树的所有规则和优点。
红黑树又增加了几个规则:
1 每个节点不是红色就是黑色的
2 根节点必须是黑色的。
3 所有的叶子节点必须是黑色的。空节点(NIL)可以认为是叶子节点。
4 红节点下不允许有红节点
5 从一个节点向下的所有路径必须有相同数量的黑节点。
第3条的空节点可以当做叶子节点这句话要解释一下,我们知道树可以当做复杂的链表,如果到链表的末尾了,再后面的节点就是空了。那么,在红黑树上,这样的空节点可以可以当做是叶子节点,是黑色的。
这里面的第5条也是很难理解,我们不去深究,咱们只要知道这些规则的目的就是为了尽可能的实现平衡的二叉查找树。
红黑树有一种左右旋的机制,可以动态的调整根节点,从而让树是平衡的。这个左右旋的意思是当某个分支的节点过多的时候,旋转一下,或者说调整一下,让相邻的节点称为根节点,从而达到树平衡的目的。这个左右旋的具体操作,有兴趣的朋友可以自己百度了解一下。在这里我就不讲这个了,这个不好讲,很难说清楚,有兴趣的可以自行百度 红黑树在线演示,网上有大牛做的动画效果,很形象的就把红黑树描述清楚了。
2.5. TreeMap的数据结构就是红黑树
最后回到TreeMap的底层来说一下,这个TreeMap的底层就是红黑树,因此,决定了TreeMap的特性:
1 TreeMap的查找和插入速度都很快,当然,查找速度依旧没有HashMap快。
2 TreeMap的键值对是有顺序的,并不是插入的先后顺序,而是大小顺序,这是因为TreeMap就是按照Key的大小顺序来组织树的。
好的,对TreeMap的解答能说到这些就没问题了。
3. 演示面试
那么,接下来就由我来进行演示面试。
面试官你好。
TreeMap的核心是红黑树,只要理解了红黑树就理解TreeMap了。
这个红黑树核心就是一个二叉树,当然,也是一个二叉查找树。
红黑树的特性有这么几条:
1 所有的节点不是红色的就是黑色的
2 红色节点下必须是黑色的节点
3 根节点必须是黑色的
4 叶子节点必须是黑色的,空节点也可以看做是叶子节点。
5 每个节点向下的所有路径,都必须有相同的黑节点。
所有这些规则的目的就是为了实现平衡的二叉查找树,从而提高元素查找的速度。
红黑树为了确保平衡,提供了节点左旋和右旋的能力,当某个节点不符合规则的时候,就可以通过旋转来重新调整相关的节点,从而得到尽可能平衡的二叉查找树。
由于TreeMap的底层是红黑树,因此就很容易解释他的一些特性了:
1 为什么TreeMap的键值对不是乱序的,也不是按照插入的先后顺序排放的,而是按照从小到大的顺序排放的,这是因为红黑树是按照节点的大小为依据组织的,所以TreeMap是按照键的大小顺序排放的。
2 TreeMap的高效性就很容易理解了,因为红黑树的性能真的 很快,它就是为了速度而生的。
关于TreeMap的底层机制我讲解完了。
4. 总结
好的,本期内容就这些,希望对您有所帮助,我们下期再见。