一、红黑树——特殊的平衡二叉搜索树
定义:红黑树是一种特殊的平衡二叉搜索树。我们用它来排列数据,并方便以后快速检索数据。
估计看到这句话,你就崩溃了,因为这话说了等于没说。
先观察这个图。
- 球要不是黑色,要不是红色,没有其他颜色,对吧?这是红黑的来源。
- 最上面的数字50是黑色的。(这个应该没有什么问题吧?)我们称它为根节点。
- 所谓的2叉,就是一个球球最多只分出去2个节点。(这个应该没有什么问题吧?)
- 10 比 50小,放在50的左边。78比50大,放在50的右边。下面的以此类推(这个应该没有什么问题吧?)
而红黑树最重要的规则,也就是它的平衡性,则体现在:
- 每个节点都有一个颜色属性,可以是红色或黑色。
- 根节点以及所有叶子节点(NIL 节点)都被视为是黑色的。
- 如果一个节点是红色的,则其子节点必定为黑色。
- 从根节点到每个叶子节点的路径上包含相同数量的黑色节点(黑色高度相等)。
叶子节点:没有分叉子节点的节点。
NIL节点:没有数据的空节点。
在红黑树里,它们其实指的是同一个节点。比如,我们先来看一张图:
如果你和我一样,90 没有分叉子节点,它不是叶子节点吗,如果是,为啥是红颜色的呢?
而当我们,把这个按钮打开,你就会发现,这个红黑树的真实样貌:
是不是茅塞顿开,NIL节点像占位符一样,确保每个节点都有2个子节点,以达到平衡的状态。
二、普通的平衡二叉搜索树
为什么说红黑树是一种特殊的平衡二叉搜索树?
这是一棵普通的平衡二叉树。
只要从根节点到叶节点路径差小于等于1就可以了。
这里的“路径”指的是从根节点到最下面的叶节点箭头数量,你可以数数看。
而红黑树对这一段数据的处理是这样的:
首先可以看到颜色和我们的红黑树就不一样,其次平衡规则不太一样。
这里不再是数路径,而是数从根节点到叶节点的黑色节点的数量。而且必须相等。
三、不平衡的二叉搜索树
那么你可能会有疑问,难道有不平衡的二叉树?
没错。如果你按照朴素的规则,小的放左边,大的放右边,很可能出现,左边没有,右边很多的画面。
这棵树已经过于倾斜,甚至出现链表状结构了,会导致操作的时间复杂度退化为O(n),此时如果你要检索一个数据,花的时间就太多了。
你可以把它理解为抽屉,抽屉里包含抽屉。每开抽屉,都要用锁(模拟查询消耗的时间 )。如果不平衡,那么花很长时间找东西。比如,我想找7,我要翻箱倒柜,一路开抽屉。
而如果排列有序(平衡的),那么不管找哪个抽屉里的东西,所花的平均时间是最少的。比如这种平衡二叉树。两边的路径长度差小于等于1。你往里插入数据,它会实时调整,保持一种平衡的状态,提高检索效率。
这里有个图形化网站可以帮助你理解这种平衡二叉树。可以自己手动插入数据,感受平衡二叉树的动态平衡。
Data Structure Visualization
最后,既然我们知道了红黑树的原理,那么我们用红黑树来干嘛呢?
没错,用来查找、插入和删除。提高检索和排序效率。
Set的实现类之一TreeSet底层用的就是红黑树原理。这也是它较之HashSet、HashLinkedSet 有序的原因。