前言

以前在了解HashMap时得知JDK8的HashMap是用红黑树实现的,而且网上还流传着手写红黑树的梗,数据结构课上也没交过这个,于是就学学吧。

一、为什么要用红黑树

因为相较于普通的二叉搜索树,红黑树具有平衡性。这与AVL树相似,在增加或删除元素后可能会出现旋转的操作。
但是相较于AVL树严格的约束(左右子树的高度之差的绝对值最多为1),红黑树的平衡约束更为宽松,其旋转操作的时间复杂度为O(1),而AVL树的旋转操作的时间复杂度为O(log n)。
因此在做增加、删除操作时可以选择红黑树,而在做搜索操作时选择AVL树(因为严格的平衡性,高度一般比红黑树低)。

二、定义

红黑树(Red Black Tree) 是一种自平衡二叉查找树。

三、性质

【数据结构】红黑树(Red Black Tree)

  1. 节点时红色或黑色
  2. 根节点是黑色
  3. 叶子节点(null节点)是黑色
  4. 红色节点的子节点都是黑色的,红色节点的父节点是黑色的
  5. 从根节点起到叶子节点的所有路径中,不能有两个连续的红色节点
  6. 从根节点起到叶子节点的所有路径中,黑色节点的个数都是相同的

为了方便起见,后面省略null节点

四、操作

1.搜索

同二叉搜索树一样,差不了多少,从根节点比大小,走分支

2.添加

添加操作比较复杂,情况比较多。

2.1.添加到黑色节点

【数据结构】红黑树(Red Black Tree)
如图,这是最简单的一种情况,粉红色的为新添加的节点,其父节点为黑色,不违反性质4。

2.2.添加到红色节点

【数据结构】红黑树(Red Black Tree)
粉色仅代表新添加的元素,本身还是红色,灰色代表待添加的元素。

2.2.1.LL型 uncle节点为黑

【数据结构】红黑树(Red Black Tree)
如图,新添加的元素60,是76左孩子的左孩子,这种类型被称之为LL型,显然LL型是不符合性质4的。
此时右旋,将72变黑,76变红,同时72变为76的父节点,即可满足性质4。
如果60有兄弟节点,则将其移动到祖节点。
【数据结构】红黑树(Red Black Tree)

2.2.2.RR型 uncle节点为黑

【数据结构】红黑树(Red Black Tree)
如图,新添加的元素52,是46右孩子的右孩子,这种类型被称之为RR型,显然RR型是不符合性质4的。
此时左旋,将50变黑,46变红,同时50变为46的父节点,即可满足性质4。
【数据结构】红黑树(Red Black Tree)

2.2.3.LR型 uncle节点为黑

【数据结构】红黑树(Red Black Tree)
旋转后
【数据结构】红黑树(Red Black Tree)

2.2.4.RL型 uncle节点为黑

【数据结构】红黑树(Red Black Tree)
旋转后
【数据结构】红黑树(Red Black Tree)

2.2.5.LL型 uncle节点为红色

【数据结构】红黑树(Red Black Tree)
将父节点,叔节点变黑,祖节点变红,如下图:
【数据结构】红黑树(Red Black Tree)
会发现,此时已然不符合性质4,但是25、38、55符合2.2.1的LL型,右旋即可。

2.2.6.RR型 uncle节点为红色

【数据结构】红黑树(Red Black Tree)
变色后
【数据结构】红黑树(Red Black Tree)
然后需要右旋

2.2.7.LR型 uncle节点为红色

【数据结构】红黑树(Red Black Tree)
变色后:
【数据结构】红黑树(Red Black Tree)
右旋

2.2.7.RL型 uncle节点为红色

相关文章: