红黑树它是一种特殊的平衡二叉树,
假设你已经对二叉树、平衡二叉树的概念有了一定的了解,
二叉树和平衡二叉树的介绍,在
通过B+Tree平衡多叉树理解InnoDB引擎的聚集和非聚集索引
有着比较清晰的描述。
有必要对平衡二叉树的旋转做一下介绍:
左旋
对y节点进行左旋:
将y节点的右子节点x作为新的父节点;
将y节点作为x节点的左子节点;
将x节点的左子节点作为y节点的右子节点。
右旋
对x节点进行左旋:
将x节点的左子节点y作为新的父节点;
将x节点作为y节点的右子节点;
将y节点的右子节点作为x节点的左子节点。
有动图大家感受一下
为什么有红黑二叉树,
平衡二叉树有着严格的平衡限制,任何一个节点左右子树的高度差不能超过1,
否则就失衡,需要旋转保持平衡,在频繁地插入或者删除节点的一些场景中,
大量的旋转操作会非常影响性能,红黑树通过牺牲严格的平衡,换来少量的旋转操作,
整体性能要优于平衡二叉树。
我们先来看下红黑树长什么样子:
算法导论中对红黑树的约束条件:
1、节点不是红的,就是黑的;
2、根节点是黑的;
3、叶节点是黑的;
4、父子节点不能同时是红的,任何分支上都不能出现两个连续的红色节点;
5、任意节点到叶节点的所有路径上,包含的黑色节点数量相同,即相同的黑色高度。
说明:
4、5保证了红黑树的大致平衡,
黑色高度为3时,
最短路径:黑→黑→黑=2;
最长路径:黑→红→黑→红→黑=4。
默认新插入的节点为红色,
因为红色不会影响路径上黑色节点的数量。
应用
Java中treemap、treeset都使用红黑树作为底层数据结构,
jdk1.8开始,hashmap也引入了红黑树。
在Java的实现中,使用黑色的空节点null来作为叶子节点。
红黑树新增节点
红黑树新增节点,可能会影响到红黑树的平衡,所以需要在进行平衡操作。
我们先约定一下关系:
子节点开始是红的,但它是根节点,需要涂黑。
无需其它操作。
需要将叔、父节点涂黑,祖父节点涂红,然后把祖父节点作为新的子节点,往上递归执行平衡操作。
父节点是祖父节点的左子节点,子节点是父节点的左子节点。
以祖父节点为支点进行右旋,然后将父节点涂黑、祖父节点涂红。
父节点涂黑是因为要涂为原祖父节点的黑色(往上兼容祖父节点的父节点),
而祖父节点涂红则是因为右旋后,经过叔节点的路径的黑色节点数量加一,涂红进行数量平衡,下同。
父节点是祖父节点的右子节点,子节点是父节点的右子节点。
以祖父节点为支点进行左旋,然后将父节点涂黑,祖父节点涂红。
父节点是祖父节点的左子节点,子节点是父节点的右子节点。
以父节点为支点进行左旋,然后以父节点作为新的平衡节点,进行同左处理。
父节点是祖父节点的右子节点,子节点是父节点的左子节点。
以父节点为支点进行右旋,然后以父节点作为新的平衡节点,进行同右处理。
新增节点:10、20、15、30、5、8。
参考文章:
路过的猪:彻底理解红黑树(二)之插入
晓之木初:红黑树详解
Just-Today:红黑树-Java实现
Geek_Ma:红黑树插入删除实例
面向c v编程:Hashmap底层实现原理(JDK1.8)(AVL树简介.红黑树的原理)