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

CS253: Balanced Binary Search Trees (2019)

CS253: Balanced Binary Search Trees (2019)

Avatar for Jinho D. Choi

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