红黑树

红黑树

红黑树可以看做是对二叉搜索树的改进,红黑树的红黑性质限制了红黑树的树高 <= 2 log(N). 以此来保证,查询,删除,插入的时间复杂度最坏情况都是 log(N)。

一颗红黑树是满足下面红黑性质的二叉搜索树

  1. 每个节点或是红色的,或是黑色的。
  2. 根节点是黑色的。
  3. 每个叶节点(NIL)是黑色的。
  4. 如果一个节点是红色的,则它的两个子节点都是黑色的。
  5. 对每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。

插入

在向一颗红黑树插入节点时,插入节点是着成红色的,因为如果插入黑色节点,很明显会破坏性质5. 除非 这颗红黑树是空树。
节点插入红黑树的过程是和二叉搜索树插入节点的方法类似。 如果插入节点的父节点是黑色时,插入节点不会破坏红黑树的性质。但是如果插入节点的父节点是红色的,会破坏性质4.
这时就需要维护红黑树的性质了。 假设插入节点为 z, z的叔节点为y.

if(z.p == z.p.p->left)

  1. z 的叔节点为红色。 叔节点着黑,父节点着黑,祖父节点着红, z 指向 祖父节点。
  2. z 的叔节点为黑色,且 z 为右孩子。z 指向父节点 然后左旋:left-rotate(T, z) // T为树根
  3. z 的叔节点为黑色,且 z 为左孩子。父节点着黑,祖父节点着红,然后右旋。right-rotate(T, z.p.p)

如果 z 的 父节点为右孩子(即:z.p == z.p.p->right),与上面过程类似,是对称的。把所有的“左”替换成“右”即可。

删除

在从红黑树中删除一个节点时,同样和从二叉搜索树中删除节点相似。 假设,我们始终维护节点 y 为从树中删除的节点或者移至树内的节点。 我们保存节点 x 的踪迹,使它移至节点 y 的原始位置上。

当 y 为红色时(无论时被直接删除的节点,还是“替补”的节点),都不会破坏红黑树的性质。如果 y 是替补节点时(即:移至树内的节点),把 y 着成被删除节点的颜色。
但是,当 y 为黑色时,红黑树的性质会被破坏。
if(x == x.p->left)

  1. x 的兄弟节点 w 为红色的。 x 的兄弟节点 w 着黑,父节点着红,然后左旋:left-rotate(T, x.p)
  2. x 的兄弟节点 w 为黑色的。 w 的两个孩子节点也都是黑色的。 w 节点着红,x 指向父节点。
  3. x 的兄弟节点 w 为黑色的。 w 的左孩子为红,右孩子为黑。 w 着红,w的左孩子着黑,然后右旋:right-rotate(T, w)
  4. x 的兄弟节点 w 为黑色的。 w 的右孩子为红。 w 节点着父节点颜色, 父节点着黑,w的右孩子节点着黑, 然后左旋:left-rotate(T, x.p)
    如果 x 为右孩子(即:z == z.p->right),与上面过程类似,是对称的。把所有的“左”替换成“右”即可。
原文地址:https://www.cnblogs.com/acm1314/p/6752391.html