zoukankan      html  css  js  c++  java
  • 红黑树

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

     旋转

    LEFT_ROTATE(T,x)

    y = x.right

    x.right = y.left

    if y.left != T.nil

      y.left.p= x

    y.p = x.p

    if x.p == T.nil

      T.root = y

    else if x == x.p.left

      x.p.left = y

    else x.p.right = y

    y.left = x

    x.p = y

    插入

     

    RB_INSERT(T,z)

    y = T.til

    x = T.root

    while x != T.til

      y = x

      if z.key < x.key

      x = x.left

      else x = x.right

    z.p = y

    if y == T.nil

      T.root = z

    else if z.key < y.key

      y.left = z

    else y.right = z

    z.left = T.nil

    z.right = T.nil

    RB_INSERT_FIXUP(T, x)

    RB_INSERT_FIXUP(T,x)

    while z.p.color == RED

      if z.p == z.p.p.left

        y = z.p.p.right

        if y.color == RED

          z.p.color = BLACK

          z.p.p.color = RED

          y.color = BLACK

        else if z == z.p.right

          z = z.p

          LEFT_ROTATE(T,z)

        esle

          z.p.color = BLACK

          z.p.p.color = RED

          RIGHT_ROTATE(T,z)

      else (same as then clause with right and left exchanged)

    T.root.color = BLACK

      

    情况1, z的叔节点y是红色的

     情况2, z的叔节点y是黑色的,且z是一个右孩子节点

     情况3, z的叔节点y是黑色的,且z是一个左孩子节点

    情况2让z指向红色的z.p ,左旋到情况3, 在情况2和情况3 颜色不改变。 把z.p改成黑色。

    删除

    RB_TRANSPLANT(T, u, v)

    if u.p = T.nil

      T.root = v

    else if u = u.p.left

      u.p.left = v

    else u.p.right = v

    v.p = u.p

    一颗二叉搜索树T中删除一个节点z的整个策略有三种基本情况

    1,z没有孩子,那么简单删除它,并修改它的父节点,用Nil作为孩子来替换它

    2,z只有一个孩子,那么将孩子提升为z的位置,并修改z的父节点,用z的孩子来替换z

    3, 如果z有两个孩子,那么找z的后继y(一定是z的右子树中),并让y占据树中z的位置,z原来右子树部分成为y的新右子树,并且z的左子树成为y的新左子树

     TREE_DELETE(T,z)

    if z.left == NIL

      TRANSPLANT(T, z, z.right)

    else if z.right == NIL

      TRANSPLANT(T, z, z.left)

    else y = TREE_MINIMUM(z.right)

      if  y.p != z

        TRANSPLANT(T, y, y.right)

        y.right = z.right

        y.right.p = y

      TRANSPLANT(T, z, y)

      y.left = z.left

      y.left.p = y

     TREE_MINIMUM(x)

      while x.left != NIL

        x = x.left

      return x

    RB_DELETE(T, z)

    y = z

    y.originalcolor = y.color

    if z.left == T.nil

      x = z.right

      RB_TRANSPLANT(T,z,z.right)

    else if z.right == T.nil

      x = z.left

      RB_TRANSPLANT(T, z, z.left)

    else y = TREE_MINIMUM(z.right)

      y.originalcolor = y.color

      x = y.right

      if y.p == z

        x.p = y

      else RB_TRANSPLANT(T, y, y.right)

        y.right = z.right

        y.right.p = y

      RB_TRANSPLANT(T, z, y)

      y.left = z.left

      y.left. p = y

      y.color = z.color

      if y.originalcolor == Black

        RB_DELETE_FIXUP(T, x)

    如果Y 是黑色的,则会产生三个问题,可以通过RB_DELETE_FIXUP进行补救。

    第一,如果y是原来的根结点。而y的一个红色的孩子成为新的根结点,这就违反了性质2

    第二,如果x,和 x.p是红色的,则违反了性质4

    第三,在树中移动y导致先前包含y的任何简单路径上黑结点个数少1,因此y的任何祖先不满足性质5

     情况1, x的兄弟节点w是红色,因为 w必须是黑颜色,所有改变w和 x.p的颜色。然后对x.p进行一次左旋。 就会将情况1,转换为2,3,4处理。这些情况由W的子节点的颜色来区分。

    情况2,x的兄弟节点为黑色,而且w的两个子节点都是黑色。因为w也是黑色的,所以从x和w上去掉一重黑色,使得x只有一重黑色,而w为红色。为了补偿从x和w去掉的一重黑色,在原来是红色或黑色的x.p

    上新增一重额外的黑色。通过将x.p作为新的节点x来重复while循环。注意到,如果通过情况1 进入到情况2,则新节点x是红黑的,因为原来的x.p是红色的。因此新的节点x.color属性值c为红色。

    情况3, x的兄弟节点w是黑色的,w的左孩子是红色的,右孩子是黑色的。交换w和左孩子的颜色,然后对w进行一次右旋。

    情况4, x的兄弟节点w是黑色的,且w的右孩子是红色的。通过进行某些颜色修改,并对x.p进行一次左旋,可以去掉x的额外黑色,从而使他变成为单重黑色。

     
  • 相关阅读:
    我的第一个博客在博客园安家了,哈哈~欢迎大家光临
    JS未设置对象问题解决方案
    关于Oracle的优化
    USACO 1.2 Milking Cows
    C语言的文件操作 freopen
    USACO 1.2 Palindromic Squares
    USACO 1.1 Broken Necklace
    ACM征程再次起航!
    USACO 1.3 Barn Repair
    USACO 1.2 Transformations
  • 原文地址:https://www.cnblogs.com/zhoug2020/p/9561579.html
Copyright © 2011-2022 走看看