红黑树

  1. 红黑树本质是一个二叉搜索树(BST),了解红黑树之前需要先了解 BST 的特性

    1. BST 的特性只有一个:在 BST 中,任何一个根节点都大于等于所有 left children,都小于所有 right children,依据这一特性,BST 可以推出以下特性:

      1. BST 中序遍历的结果为一个有序的列表

      2. 查找 key:从根节点查找,小于当前节点再从left child 开始查找,大于当前节点则从right child 开始查找,直到查找到或者到叶子结点为止

      3. 最小值:二叉树的最左节点

      4. 最大值:二叉树的最大节点

      5. 前驱:

        1. 如果有left child,则为以left child 为根的最大值

        2. 如果没有 left child,再判断当前节点是否为root

          1. 如果是,没有前驱

          2. 如果不是,找到当前节点为 parent 的 right child 的那个 parent 节点,如果没有那个 parent,就没有前驱

      6. 后继:

        1. 如果有right child,则为以right child 为根的最小值

        2. 如果没有 right child,再判断当前节点是否为root

          1. 如果是,没有后继

          2. 如果不是,找到当前节点为 parent 的 left child 的那个 parent 节点,如果没有那个 parent,就没有后继

      7. 插入操作:要插入的 key 小于等于当前节点以 left child 为当前节点继续递归插入,要插入的 key 小于当前节点以right child 为当前节点继续递归插入,直到 child 为null 位置,child 为null 的位置就是要插入的位置。

      8. 删除操作:

        1. 如果要删除的节点没有 child,直接删除

        2. 如果只有一个 child,用 child 代替要删除的节点

        3. 如果有两个 child,找到后继节点,用后继节点的 key 替换要删除的那个节点的 key,接着递归删除后继节点操作

  2. 了解红黑树之前,还需要知道两个操作,左旋和右旋

    1. 左旋:以parent 为支点,原parent 变成 原 right child 的 left child,原 right child 变成 parent,原 right child 的 left child 变成原parent 的 right child,左旋完成后 BST 的特性不变

    2. 右旋:以parent 为支点,原parent 变成 原 left child 的right child,原 left child 变成 parent,原 left child 的 right child 变成原parent 的 left child,右旋完成后 BST 的特性不变

  3. 红黑树特性

    1. 每个 node 只能是 red 或 black

    2. 根节点是black

    3. leaf 节点数据为 NIL 且每个 leaf 结点是 black

    4. 如果一个 node 是 red,则它的 children 必须是 black

    5. 从一个 node 到其 children 的所有路径上包含相同的 black node 数量

  4. 红黑树操作 -- 添加:

    1. 将红黑树视为 BST,将节点插入

    2. 将插入的节点标记为 red

    3. 通过一系列插入修正操作,使之重新成为一颗红黑树

  5. 红黑树操作 -- 添加时的插入修正操作:红黑树添加得第3步的具体插入修正操作可以分成3类:

    1. 被插入的节点是根节点:直接标记为 black

    2. 被插入的节点的 parent 节点是 black:什么都不做

    3. 被插入的节点的 parent 是 red:此时,又可根据 uncle 节点来分为3类操作

      1. 当前节点的 parent 节点是红色,且 uncle 节点也是红色,操作流程为:

        1. 将 parent 和 uncle 标为黑色

        2. 将 grandparent 标为 红色

        3. 以 grandparent 为当前节点继续递归修正

      2. 当前节点的 parent 是 red,且是其 parent 的 left child,uncle 是 black ,操作流程为:

        1. 将 parent 设置为 black

        2. 将 grandparent 标为 red

        3. 以 grandparent 为支点右旋

      3. 当前节点的 parent 是红色,且是其 parent 的 right child,操作流程为:

        1. 以 parent 为支点进行左旋

        2. 左旋完成后变成情况2,按情况2 继续调整即可

      注意:上述 3 种情况都是以插入到 parent 的 left child 为前提的,如果是插入到 right child,执行与上述情况的镜像操作即可

  6. 红黑树操作 -- 删除:

    1. 将红黑树视为一个 BST 来删除节点,这有3类情况:

      1. 待删除的节点是 red,直接删除即可

      2. 待删除的节点是 black,要顶替的节点是 red, 先删除,然后将要顶替的节点变成 black 即可

      3. 待删除的节点是 black,要顶替的节点也是 black,此时先删除,然后以要顶替的节点 为 x,通过一系列删除修正操作,使之重新成为一颗红黑树

  7. 红黑树操作 -- 删除修正:红黑树的删除修正可分为以下 6 种情况:

    1. x 是 root 节点,什么都不用做

    2. x 的 parent、sibling、nephews 都是 black

      1. 把 x 的 sibling 变成 red 即可

      2. 以 x 的 parent 为当前节点继续递归进行删除修正操作

    3. x 的 parent 是 red,sibling 和 nephews 是 black

      1. 将 parent 变成 black,此时变成了情况2,再按情况2 继续调整即可

    4. x 的 parent 颜色随意,sibling 是 black,sibling 的 right child 是 red

      1. parent 和 sibling 颜色交换,sibling 的 right child 变为 black 

      2. 以 x 的 parent 为支点左旋

    5. x 的 parent 颜色随意,sibling 是 black,sibling 的 left child 是 red

      1. sibling 标为 red,原 sibling 的 left child 标为 black

      2. 以 sibling 为支点右旋

      3. 此时变成了情况3,再按情况3 继续调整即可

    6. x 的 sibling 是 red

      1. parent 变成 red,sibling 变成 black

      2. 以 x 的 parent 为支点进行左旋

      3. 此时只可能会变成情况 3、4、5,继续按所变成的情况继续操作即可

    注意:上述 6 种情况都是以 x 是 parent 的 left child 为前提的,如果 x 是 parent 的 right child,执行与上述情况的镜像操作即可

posted @ 2021-09-21 23:23  programmLover  阅读(50)  评论(0编辑  收藏  举报