[关闭]
@Alllll0235 2017-07-30T06:55:21.000000Z 字数 7033 阅读 1111

Red-Black Trees

learning


1. properties of red-black trees

  1. Every node is either red or black.
  2. The root is black.
  3. Every leaf (NIL) is black.
  4. If a node is red, then both its children are black.
  5. For each node, all simple paths from the node to descendant leaves contain the same number of balck nodes.

Lemma: A red-black tree with internal nodes has height at most

Proof: 当 internal nodes 全为黑时,internal nodes 的数目为 ,也就是说,一颗红黑树至少有个 internal nodes 。由性质4得,当黑节点数目一定时,要使得 internal nodes 数目最多,则父节点与子节点的颜色红黑相间,也就是说,从根节点到叶节点(不包括根节点)的任何一条简单路径上都至少有一半的节点为黑色。所以,(其中,h为树的高度)。化简得,

2. Rotation

left-rotation

  1. /*
  2. * 对红黑树的节点(x)进行左旋转
  3. *
  4. * 左旋示意图(对节点x进行左旋):
  5. * px px
  6. * / /
  7. * x y
  8. * / \ --(左旋)--> / \ #
  9. * lx y x ry
  10. * / \ / \
  11. * ly ry lx ly
  12. *
  13. *
  14. */
  15. template <class T>
  16. void RBTree<T>::leftRotate(RBTNode<T>* &root, RBTNode<T>* x)
  17. {
  18. // 设x的右孩子为y
  19. RBTNode<T> *y = x->right;
  20. // 将y的左孩子设为x的右孩子
  21. // 如果y的左孩子非空,将x设为y的左孩子的父亲
  22. x->right = y->left;
  23. if (y->left != NULL)
  24. y->left->parent = x;
  25. // 将 “x的父亲” 设为 “y的父亲”
  26. y->parent = x->parent;
  27. if (x->parent == NULL)
  28. {
  29. root = y;
  30. // 如果 “x的父亲” 是空节点,则将y设为根节点
  31. }
  32. else
  33. {
  34. if (x->parent->left == x)
  35. x->parent->left = y;
  36. // 如果x是它父节点的左孩子,则将y设为“x的父节点的左孩子”
  37. else
  38. x->parent->right = y;
  39. // 如果x是它父节点的左孩子,则将y设为“x的父节点的左孩子”
  40. }
  41. // 将 “x” 设为 “y的左孩子”
  42. y->left = x;
  43. // 将 “x的父节点” 设为 “y”
  44. x->parent = y;
  45. }
  1. /*
  2. * 对红黑树的节点(y)进行右旋转
  3. *
  4. * 右旋示意图(对节点y进行左旋):
  5. * py py
  6. * / /
  7. * y x
  8. * / \ --(右旋)--> / \ #
  9. * x ry lx y
  10. * / \ / \ #
  11. * lx rx rx ry
  12. *
  13. */
  14. template <class T>
  15. void RBTree<T>::rightRotate(RBTNode<T>* &root, RBTNode<T>* y)
  16. {
  17. // 设置x是当前节点的左孩子。
  18. RBTNode<T> *x = y->left;
  19. // 将 “x的右孩子” 设为 “y的左孩子”;
  20. // 如果"x的右孩子"不为空的话,将 “y” 设为 “x的右孩子的父亲”
  21. y->left = x->right;
  22. if (x->right != NULL)
  23. x->right->parent = y;
  24. // 将 “y的父亲” 设为 “x的父亲”
  25. x->parent = y->parent;
  26. if (y->parent == NULL)
  27. {
  28. root = x;
  29. // 如果 “y的父亲” 是空节点,则将x设为根节点
  30. }
  31. else
  32. {
  33. if (y == y->parent->right)
  34. y->parent->right = x;
  35. // 如果y是它父节点的右孩子,则将x设为“y的父节点的右孩子”
  36. else
  37. y->parent->left = x;
  38. // (y是它父节点的左孩子) 将x设为“x的父节点的左孩子”
  39. }
  40. // 将 “y” 设为 “x的右孩子”
  41. x->right = y;
  42. // 将 “y的父节点” 设为 “x”
  43. y->parent = x;
  44. }

3.Insertion

  1. /*
  2. * 参数说明:
  3. * root 红黑树的根结点
  4. * node 插入的结点 // 对应《算法导论》中的node
  5. */
  6. template <class T>
  7. void RBTree<T>::insert(RBTNode<T>* &root, RBTNode<T>* node)
  8. {
  9. RBTNode<T> *y = NULL;
  10. RBTNode<T> *x = root;
  11. /*1. Insert node z into the tree as if it were an ordinary binary search tree*/
  12. while (x != NULL)
  13. {
  14. y = x;
  15. if (node->key < x->key)
  16. x = x->left;
  17. else
  18. x = x->right;
  19. }
  20. node->parent = y;
  21. if (y!=NULL)
  22. {
  23. if (node->key < y->key)
  24. y->left = node;
  25. else
  26. y->right = node;
  27. }
  28. else
  29. root = node;
  30. // 2. color z red
  31. node->color = RED;
  32. /* 3. call an auxiliary procedure RB—INSERT-FIXUP to recolor nodes and perform rotations*/
  33. insertFixUp(root, node);
  34. }

insert_fixup

insert_fixup

insert_fixup
Same as then clause with "right" and "left" exchanged.

  1. *
  2. * 红黑树插入修正函数
  3. *
  4. * 在向红黑树中插入节点之后(失去平衡),再调用该函数;
  5. * 目的是将它重新塑造成一颗红黑树。
  6. *
  7. * 参数说明:
  8. * root 红黑树的根
  9. * node 插入的结点 // 对应《算法导论》中的z
  10. */
  11. template <class T>
  12. void RBTree<T>::insertFixUp(RBTNode<T>* &root, RBTNode<T>* node)
  13. {
  14. RBTNode<T> *parent, *gparent;
  15. // 若“父节点存在,并且父节点的颜色是红色”
  16. while ((parent = rb_parent(node)) && rb_is_red(parent))
  17. {
  18. gparent = rb_parent(parent);
  19. //若“父节点”是“祖父节点的左孩子”
  20. if (parent == gparent->left)
  21. {
  22. // Case 1 z's uncle y is red
  23. {
  24. RBTNode<T> *uncle = gparent->right;
  25. if (uncle && rb_is_red(uncle))
  26. {
  27. rb_set_black(uncle);
  28. rb_set_black(parent);
  29. rb_set_red(gparent);
  30. node = gparent;
  31. continue;
  32. }
  33. }
  34. // Case 2 z's uncle y is black and z is a right child
  35. if (parent->right == node)
  36. {
  37. RBTNode<T> *tmp;
  38. leftRotate(root, parent);
  39. tmp = parent;
  40. parent = node;
  41. node = tmp;
  42. }
  43. // Case 3 z's uncle y is black and z is a left child
  44. rb_set_black(parent);
  45. rb_set_red(gparent);
  46. rightRotate(root, gparent);
  47. }
  48. else//若“z的父节点”是“z的祖父节点的右孩子”
  49. {
  50. // Case 1 z's uncle y is red
  51. {
  52. RBTNode<T> *uncle = gparent->left;
  53. if (uncle && rb_is_red(uncle))
  54. {
  55. rb_set_black(uncle);
  56. rb_set_black(parent);
  57. rb_set_red(gparent);
  58. node = gparent;
  59. continue;
  60. }
  61. }
  62. // Case 2 z's uncle y is black and z is a left child
  63. if (parent->left == node)
  64. {
  65. RBTNode<T> *tmp;
  66. rightRotate(root, parent);
  67. tmp = parent;
  68. parent = node;
  69. node = tmp;
  70. }
  71. // Case 3 z's uncle y is black and z is a right child
  72. rb_set_black(parent);
  73. rb_set_red(gparent);
  74. leftRotate(root, gparent);
  75. }
  76. }
  77. // color root node black
  78. rb_set_black(root);
  79. }

4. Deletion

  1. /*
  2. * 参数说明:
  3. * root 红黑树的根结点
  4. * node 删除的结点
  5. */
  6. template <class T>
  7. void RBTree<T>::remove(RBTNode<T>* &root, RBTNode<T> *node)
  8. {
  9. RBTNode<T> *child, *parent;
  10. RBTColor color;
  11. // 被删除节点的"左右孩子都不为空"的情况。
  12. if ( (node->left!=NULL) && (node->right!=NULL) )
  13. {
  14. // 被删节点的后继节点。(称为"取代节点")
  15. // 用它来取代"被删节点"的位置,然后再将"被删节点"去掉。
  16. RBTNode<T> *replace = node;
  17. // 获取后继节点
  18. replace = replace->right;
  19. while (replace->left != NULL)
  20. replace = replace->left;
  21. // "node节点"不是根节点(只有根节点不存在父节点)
  22. if (rb_parent(node))
  23. {
  24. if (rb_parent(node)->left == node)
  25. rb_parent(node)->left = replace;
  26. else
  27. rb_parent(node)->right = replace;
  28. }
  29. else
  30. // "node节点"是根节点,更新根节点。
  31. root = replace;
  32. // child是"取代节点"的右孩子,也是需要"调整的节点"。
  33. // "取代节点"肯定不存在左孩子!因为它是一个后继节点。
  34. child = replace->right;
  35. parent = rb_parent(replace);
  36. // 保存"取代节点"的颜色
  37. color = rb_color(replace);
  38. // "被删除节点"是"它的后继节点的父节点"
  39. if (parent == node)
  40. {
  41. parent = replace;
  42. }
  43. else
  44. {
  45. // child不为空
  46. if (child)
  47. rb_set_parent(child, parent);
  48. parent->left = child;
  49. replace->right = node->right;
  50. rb_set_parent(node->right, replace);
  51. }
  52. replace->parent = node->parent;
  53. replace->color = node->color;
  54. replace->left = node->left;
  55. node->left->parent = replace;
  56. if (color == BLACK)
  57. removeFixUp(root, child, parent);
  58. delete node;
  59. return ;
  60. }
  61. if (node->left !=NULL)
  62. child = node->left;
  63. else
  64. child = node->right;
  65. parent = node->parent;
  66. // 保存"取代节点"的颜色
  67. color = node->color;
  68. if (child)
  69. child->parent = parent;
  70. // "node节点"不是根节点
  71. if (parent)
  72. {
  73. if (parent->left == node)
  74. parent->left = child;
  75. else
  76. parent->right = child;
  77. }
  78. else
  79. root = child;
  80. if (color == BLACK)
  81. removeFixUp(root, child, parent);
  82. delete node;
  83. }
  1. /*
  2. * 红黑树删除修正函数
  3. *
  4. * 在从红黑树中删除插入节点之后(红黑树失去平衡),再调用该函数;
  5. * 目的是将它重新塑造成一颗红黑树。
  6. *
  7. * 参数说明:
  8. * root 红黑树的根
  9. * node 待修正的节点
  10. */
  11. template <class T>
  12. void RBTree<T>::removeFixUp(RBTNode<T>* &root, RBTNode<T> *node, RBTNode<T> *parent)
  13. {
  14. RBTNode<T> *other;
  15. while ((!node || rb_is_black(node)) && node != root)
  16. {
  17. if (parent->left == node)
  18. {
  19. other = parent->right;
  20. if (rb_is_red(other))
  21. {
  22. // Case 1 x's sibling w is red
  23. rb_set_black(other);
  24. rb_set_red(parent);
  25. leftRotate(root, parent);
  26. other = parent->right;
  27. }
  28. if ((!other->left || rb_is_black(other->left)) &&
  29. (!other->right || rb_is_black(other->right)))
  30. {
  31. /*Case 2 x's sibling w is black, and both of w's children are black*/
  32. rb_set_red(other);
  33. node = parent;
  34. parent = rb_parent(node);
  35. }
  36. else
  37. {
  38. if (!other->right || rb_is_black(other->right))
  39. {
  40. /* Case 3 x's sibling w is black, w's left child is red, and w's right child is black*/
  41. rb_set_black(other->left);
  42. rb_set_red(other);
  43. rightRotate(root, other);
  44. other = parent->right;
  45. }
  46. /* Case 4 x's sibling w is black, and w's right child is red*/
  47. rb_set_color(other, rb_color(parent));
  48. rb_set_black(parent);
  49. rb_set_black(other->right);
  50. leftRotate(root, parent);
  51. node = root;
  52. break;
  53. }
  54. }
  55. else
  56. {
  57. other = parent->left;
  58. if (rb_is_red(other))
  59. {
  60. // Case 1 x's sibling w is red
  61. rb_set_black(other);
  62. rb_set_red(parent);
  63. rightRotate(root, parent);
  64. other = parent->left;
  65. }
  66. if ((!other->left || rb_is_black(other->left)) &&
  67. (!other->right || rb_is_black(other->right)))
  68. {
  69. /*Case 2 x's sibling w is black, and both of w's children are black*/
  70. rb_set_red(other);
  71. node = parent;
  72. parent = rb_parent(node);
  73. }
  74. else
  75. {
  76. if (!other->left || rb_is_black(other->left))
  77. {
  78. /* Case 3 x's sibling w is black, w's right child is red, and w's left child is black*/
  79. rb_set_black(other->right);
  80. rb_set_red(other);
  81. leftRotate(root, other);
  82. other = parent->left;
  83. }
  84. /* Case 4 x's sibling w is black, and w's left child is red*/
  85. rb_set_color(other, rb_color(parent));
  86. rb_set_black(parent);
  87. rb_set_black(other->left);
  88. rightRotate(root, parent);
  89. node = root;
  90. break;
  91. }
  92. }
  93. }
  94. if (node)
  95. rb_set_black(node);
  96. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注