Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CS253: Balanced Binary Search Trees (2019)

CS253: Balanced Binary Search Trees (2019)

Jinho D. Choi

October 02, 2019
Tweet

More Decks by Jinho D. Choi

Other Decks in Technology

Transcript

  1. Binary Search Trees: Balanced Data Structures and Algorithms Emory University

    Jinho D. Choi https://github.com/emory-courses/cs253
  2. AbstractBalancedBinarySearchTree.java public abstract class AbstractBalancedBinarySearchTree <T extends Comparable<T>, N extends

    AbstractBinaryNode<T, N>> extends AbstractBinarySearchTree<T, N> { @Override public N add(T key) { N node = super.add(key); balance(node); return node; } @Override public N remove(T key) { N node = findNode(root, key); if (node != null) { N lowest = node.hasBothChildren() ? removeHibbard(node) : removeSelf(node); if (lowest != null && lowest != node) balance(lowest); } return node; } /** Preserves the balance of the specific node and its ancestors. */ protected abstract void balance(N node); balance()
  3. Balanced BST - Rotate Left 2 5 3 7 1

    4 6 8 10 N child = node.getRightChild();
  4. Balanced BST - Rotate Left 2 5 3 7 1

    4 6 8 10 N child = node.getRightChild();
  5. Balanced BST - Rotate Left 2 5 3 7 1

    4 6 8 10 N child = node.getRightChild(); node.setRightChild(child.getLeftChild());
  6. Balanced BST - Rotate Left 2 5 3 7 1

    4 6 8 10 N child = node.getRightChild(); node.setRightChild(child.getLeftChild());
  7. Balanced BST - Rotate Left 2 5 3 7 1

    4 6 8 10 N child = node.getRightChild(); node.setRightChild(child.getLeftChild()); node.getParent().replaceChild(node, child);
  8. Balanced BST - Rotate Left 2 5 3 7 1

    4 6 8 10 N child = node.getRightChild(); node.setRightChild(child.getLeftChild()); node.getParent().replaceChild(node, child);
  9. Balanced BST - Rotate Left 2 5 3 7 1

    4 6 8 10 N child = node.getRightChild(); node.setRightChild(child.getLeftChild()); node.getParent().replaceChild(node, child); child.setLeftChild(node);
  10. Balanced BST - Rotate Left 2 5 3 7 1

    4 6 8 10 N child = node.getRightChild(); node.setRightChild(child.getLeftChild()); node.getParent().replaceChild(node, child); child.setLeftChild(node);
  11. protected void rotateLeft(N node) { N child = node.getRightChild(); node.setRightChild(child.getLeftChild());

    if (node.hasParent()) node.getParent().replaceChild(node, child); else setRoot(child); child.setLeftChild(node); } protected void rotateRight(N node) { N child = node.getLeftChild(); node.setLeftChild(child.getRightChild()); if (node.hasParent()) node.getParent().replaceChild(node, child); else setRoot(child); child.setRightChild(node); }
  12. AVLNode.java public class AVLNode<T extends Comparable<T>> extends AbstractBinaryNode<T, AVLNode<T>> {

    private int height; public AVLNode(T key) { super(key); height = 1; } @Override public void setLeftChild(AVLNode<T> node) { super.setLeftChild(node); resetHeights(); } @Override public void setRightChild(AVLNode<T> node) { super.setRightChild(node); resetHeights(); }
  13. public void resetHeights() { resetHeightsAux(this); } private void resetHeightsAux(AVLNode<T> node)

    { if (node != null) { int lh = node.hasLeftChild() ? node.getLeftChild().getHeight() : 0; int rh = node.hasRightChild() ? node.getRightChild().getHeight() : 0; int height = Math.max(lh, rh) + 1; if (height != node.getHeight()) { node.setHeight(height); resetHeightsAux(node.getParent()); } } }
  14. public int getBalanceFactor() { if (hasBothChildren()) return left_child.getHeight() - right_child.getHeight();

    else if (hasLeftChild()) return left_child.getHeight(); else if (hasRightChild()) return -right_child.getHeight(); else return 0; }
  15. AVLTree.java public class AVLTree<T extends Comparable<T>> extends AbstractBalancedBinarySearchTree<T, AVLNode<T>> {

    @Override public AVLNode<T> createNode(T key) { return new AVLNode<T>(key); } @Override protected void rotateLeft(AVLNode<T> node) { super.rotateLeft(node); node.resetHeights(); } @Override protected void rotateRight(AVLNode<T> node) { super.rotateRight(node); node.resetHeights(); }
  16. @Override protected void balance(AVLNode<T> node) { if (node == null)

    return; int bf = node.getBalanceFactor(); if (bf == 2) { AVLNode<T> child = node.getLeftChild(); if (child.getBalanceFactor() == -1) // case 1 rotateLeft(child); rotateRight(node); // case 2 } else if (bf == -2) { AVLNode<T> child = node.getRightChild(); if (child.getBalanceFactor() == 1) // case 3 rotateRight(child); rotateLeft(node); // case 4 } else balance(node.getParent()); }
  17. AVL Tree - Add 3 1 5 3 1 |Balance

    factor| > 1? Rotate right 3 5
  18. AVL Tree - Add 3 1 5 3 1 |Balance

    factor| > 1? Rotate right 3 5
  19. AVL Tree - Add 3 1 5 3 1 4

    |Balance factor| > 1? Rotate right 3 5
  20. AVL Tree - Add 3 1 4 5 3 1

    4 |Balance factor| > 1? Rotate right 3 5
  21. AVL Tree - Add 3 1 4 5 3 1

    4 2 |Balance factor| > 1? Rotate right 3 5
  22. AVL Tree - Add 3 1 4 2 5 3

    1 4 2 |Balance factor| > 1? Rotate right 3 5
  23. AVL Tree - Add 3 1 4 2 5 3

    1 4 2 8 |Balance factor| > 1? Rotate right 3 5
  24. AVL Tree - Add 3 1 4 2 5 3

    1 4 2 8 |Balance factor| > 1? Rotate right 3 5 8
  25. AVL Tree - Add 3 1 4 2 5 3

    1 4 2 8 6 |Balance factor| > 1? Rotate right 3 5 8
  26. AVL Tree - Add 3 1 4 2 5 3

    1 4 2 8 6 |Balance factor| > 1? Rotate right 3 5 8 6
  27. AVL Tree - Add 3 1 4 2 5 3

    1 4 2 8 6 7 |Balance factor| > 1? Rotate right 3 5 8 6
  28. AVL Tree - Add 3 1 4 2 5 3

    1 4 2 8 6 7 |Balance factor| > 1? Rotate right 3 5 7 8 6
  29. AVL Tree - Add 3 1 4 2 5 3

    1 4 2 8 6 7 |Balance factor| > 1? Rotate right 3 5 Rotate left 7 8 6
  30. AVL Tree - Add 3 1 4 2 5 3

    1 4 2 8 6 7 |Balance factor| > 1? Rotate right 3 5 Rotate left 7 8 6
  31. AVL Tree - Add 3 1 4 2 5 3

    1 4 2 8 6 7 |Balance factor| > 1? Rotate right 3 5 Rotate left 7 8 Rotate right 6
  32. AVL Tree - Add 3 1 4 2 5 3

    1 4 2 8 6 7 |Balance factor| > 1? Rotate right 3 5 Rotate left 7 8 Rotate right 6
  33. RedBlackTree.java public class RedBlackTree<T extends Comparable<T>> extends AbstractBalancedBinarySearchTree<T, RedBlackNode<T>> {

    public RedBlackNode<T> createNode(T key) { return new RedBlackNode<T>(key); } protected void balance(RedBlackNode<T> node) { if (isRoot(node)) node.setToBlack(); else if (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } } private void balanceWithRedUncle(RedBlackNode<T> node, RedBlackNode<T> uncle) { node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); }
  34. private void balanceWithBlackUncle(RedBlackNode<T> node) { RedBlackNode<T> grandParent = node.getGrandParent(); if

    (grandParent != null) { RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { // case 1 rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { // case 2 rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) // case 3 rotateRight(grandParent); else rotateLeft(grandParent); // case 4 } }
  35. Red-Black - Add 4 if (isRoot(node)) node.setToBlack(); else if (node.getParent().isRed())

    { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent);
  36. 5 Red-Black - Add 4 if (isRoot(node)) node.setToBlack(); else if

    (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent);
  37. 5 Red-Black - Add 4 if (isRoot(node)) node.setToBlack(); else if

    (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent);
  38. Red-Black - Add 4 5 if (isRoot(node)) node.setToBlack(); else if

    (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent);
  39. Red-Black - Add 4 3 5 if (isRoot(node)) node.setToBlack(); else

    if (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent);
  40. Red-Black - Add 4 1 3 5 if (isRoot(node)) node.setToBlack();

    else if (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent);
  41. Red-Black - Add 4 1 3 5 if (isRoot(node)) node.setToBlack();

    else if (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent);
  42. Red-Black - Add 4 1 3 5 if (isRoot(node)) node.setToBlack();

    else if (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent);
  43. Red-Black - Add 4 1 if (isRoot(node)) node.setToBlack(); else if

    (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent); 3 5
  44. Red-Black - Add 4 1 if (isRoot(node)) node.setToBlack(); else if

    (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent); 3 5
  45. Red-Black - Add 4 1 if (isRoot(node)) node.setToBlack(); else if

    (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent); 3 5
  46. Red-Black - Add 4 1 4 if (isRoot(node)) node.setToBlack(); else

    if (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent); 3 5
  47. Red-Black - Add 4 1 4 if (isRoot(node)) node.setToBlack(); else

    if (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent); 3 5
  48. Red-Black - Add 4 1 4 if (isRoot(node)) node.setToBlack(); else

    if (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent); 3 5
  49. 5 Red-Black - Add 4 4 if (isRoot(node)) node.setToBlack(); else

    if (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent); 3 1
  50. 5 Red-Black - Add 4 4 if (isRoot(node)) node.setToBlack(); else

    if (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent); 3 1
  51. 5 Red-Black - Add 4 4 if (isRoot(node)) node.setToBlack(); else

    if (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent); 1 3
  52. 5 Red-Black - Add 4 4 if (isRoot(node)) node.setToBlack(); else

    if (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent); 1 3
  53. 5 Red-Black - Add 4 4 if (isRoot(node)) node.setToBlack(); else

    if (node.getParent().isRed()) { RedBlackNode<T> uncle = node.getUncle(); if (uncle != null && uncle.isRed()) balanceWithRedUncle(node, uncle); else balanceWithBlackUncle(node); } node.getParent().setToBlack(); uncle.setToBlack(); RedBlackNode<T> grandParent = node.getGrandParent(); grandParent.setToRed(); balance(grandParent); RedBlackNode<T> parent = node.getParent(); if (grandParent.isLeftChild(parent) && parent.isRightChild(node)) { rotateLeft(parent); node = parent; } else if (grandParent.isRightChild(parent) && parent.isLeftChild(node)) { rotateRight(parent); node = parent; } node.getParent().setToBlack(); grandParent.setToRed(); if (node.getParent().isLeftChild(node)) rotateRight(grandParent); else rotateLeft(grandParent); 1 3