红黑树

1,071 阅读3分钟

「这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战

性质:

  1. 结点是红色或黑色。

  2. 根结点是黑色。

  3. 每个叶子结点都是黑色的空结点(NIL结点)。

  4. 每个红色结点的两个子结点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色结点)

  5. 从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点。

观察下图是红黑树吗?

看似是对的,实则是错的,看最后一条性质从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点。这里的叶子节点是指NIL节点,像节点30有一个右NIL叶子节点,从51到此节点经过2个黑节点,从51到20的左/右的NIL叶子节点要经过3个黑色节点,不满足性质五,故不是红黑树。

添加

一般新添加的节点默认为红色,可以使红黑树的性质尽快满足,默认为红色除了性质4不能立即满足,其余都可以。添加的若是根节点,则为黑色,由性质2得到。

以下新添加默认都为红色

情况1:父节点为黑色

由于新添加的节点默认为红色,因此此时仍然满足红黑树的性质,整棵树不用做任何调整。

情况2:父节点为红色,叔父节点不为红色

LL

父节点染成黑色,祖父节点染成红色,祖父节点像AVL树的LL情况一样右旋

RR

父节点染成黑色,祖父节点染成红色,祖父节点像AVL树的RR情况一样左旋

LR

此节点染成黑色,祖父节点染成红色,父节点像AVL树的LR情况一样左旋,祖父节点像AVL树的LR情况一样右旋

RL

此节点染成黑色,祖父节点染成红色,父节点像AVL树的RL情况一样右旋,祖父节点像AVL树的RL情况一样左旋

情况3:父节点为红色,叔父节点为红色

LL

父节点染成黑色,祖父节点染成红色,叔父节点染成黑色,若祖父的父节点为红色,把祖父节点向上看成新添加的红节点看待添加进去(类似于情况2)

RR

父节点染成黑色,祖父节点染成红色,叔父节点染成黑色,若祖父的父节点为红色,把祖父节点向上看成新添加的红节点看待添加进去(类似于情况2)

LR

父节点染成黑色,祖父节点染成红色,叔父节点染成黑色,若祖父的父节点为红色,把祖父节点向上看成新添加的红节点看待添加进去(类似于情况2)

RL

父节点染成黑色,祖父节点染成红色,叔父节点染成黑色,若祖父的父节点为红色,把祖父节点向上看成新添加的红节点看待添加进去(类似于情况2)

删除

情况1:删除红色节点

直接删除不用调整

情况2:删除黑色节点

拥有2个红节点

寻找子节点替代删除

拥有一个字节点且为红节点

直接将字节点染黑,直接删掉该节点即可