예제 #1
0
    def _delete(self, node: ColorNode, val: int) -> Union[ColorNode, None]:
        """
        Private method to delete a node with the given value from the substree specified by node.
        """
        if val < node.val:
            if (not self._is_red(node.left)) and (not self._is_red(
                    node.left.left)):
                node = self._move_red_left(node)
            node.left = self._delete(node.left, val)

        else:
            if self._is_red(node.left):
                node = self._rotate_right(node)
            if val == node.val and node.right == None:
                return None
            if (not self._is_red(node.right)) and (not self._is_red(
                    node.right.left)):
                node = self._move_red_right(node)
            if val == node.val:
                x = self._min(node.right)
                node.val = x.val
                node.right = self._del_min(node.right)
            else:
                node.right = self._delete(node.right, val)

        return self._balance(node)
예제 #2
0
def test_color_node():
    c_node = ColorNode(1, color=Color.RED)
    assert c_node.color == Color.RED
    c_node.color = Color.BLACK
    assert c_node.color == Color.BLACK
    assert c_node.val == 1
    assert c_node.left == None
    assert c_node.right == None
예제 #3
0
def my_tree_2():
    root = ColorNode(8)
    root.left = ColorNode(5)
    root.right = ColorNode(11)
    root.left.left = ColorNode(3)
    root.left.right = ColorNode(6)
    root.right.left = ColorNode(10)
    root.right.right = ColorNode(13)

    return root
예제 #4
0
 def _rotate_right(self, node: ColorNode) -> ColorNode:
     """
     The node's left child is red. Perform right-rotation to make the node's right child red.
     """
     x = node.left
     node.left = x.right
     x.right = node
     x.color = node.color
     node.color = Color.RED
     return x
예제 #5
0
 def _rotate_left(self, node: ColorNode) -> ColorNode:
     """
     The node's right child is red. Perform left-rotation to comply red-left-leaning rule.
     """
     x = node.right
     node.right = x.left
     x.left = node
     x.color = node.color
     node.color = Color.RED
     return x
예제 #6
0
def my_tree():
    root = ColorNode(6, color=Color.BLACK)
    root.left = ColorNode(4, color=Color.RED)
    root.left.left = ColorNode(2, color=Color.BLACK)
    root.left.right = ColorNode(5, color=Color.BLACK)
    root.right = ColorNode(8, color=Color.BLACK)
    root.right.left = ColorNode(7, color=Color.RED)

    return root
예제 #7
0
    def _flip_color(self, node: ColorNode) -> None:
        """
        Flip the color of the node and its children.
        """
        if node.color == Color.RED:
            node.color = Color.BLACK
        else:
            node.color = Color.RED

        if node.left.color == Color.RED:
            node.left.color = Color.BLACK
        else:
            node.left.color = Color.RED

        if node.right.color == Color.RED:
            node.right.color = Color.BLACK
        else:
            node.right.color = Color.RED
예제 #8
0
 def _del_max(self, node: ColorNode) -> None:
     if self._is_red(node.left):
         node = self._rotate_right(node)
     if node.right == None:
         return None
     if (not self._is_red(node.right)) and (not self._is_red(
             node.right.left)):
         node = self._move_red_right(node)
     node.right = self._del_max(node.right)
     return self._balance(node)
예제 #9
0
 def _del_min(self, node: ColorNode) -> Union[ColorNode, None]:
     """
     Private method to delete the minimum key in the tree.
     """
     if node.left == None:
         return None
     if (not self._is_red(node.left)) and (not self._is_red(
             node.left.left)):
         node = self._move_red_left(node)
     node.left = self._del_min(node.left)
     return self._balance(node)
예제 #10
0
 def _move_red_left(self, node: ColorNode) -> ColorNode:
     """
     Assume that node is red and both node.left and node.left.left are black.
     Make node.left or one of its children red.
     """
     self._flip_color(node)
     if self._is_red(node.right.left):
         node.right = self._rotate_right(node.right)
         node = self._rotate_left(node)
         self._flip_color(node)
     return node
예제 #11
0
    def _add(self, node: ColorNode, val: int) -> ColorNode:
        """
        Overwrite BST's _add method with ColorNode.
        """
        if node == None:
            # Always set the newly added color to RED, then use the
            # operations to maintain the restrictions. Think about how a
            # new node is added in a 2-3 tree helps.
            return ColorNode(val, color=Color.RED)
        if val < node.val:
            node.left = self._add(node._left, val)
        elif val > node.val:
            node.right = self._add(node._right, val)

        # maintain red-black rules. See Algorithms page 438 for details.
        if self._is_red(node.right) and not self._is_red(node.left):
            node = self._rotate_left(node)
        if self._is_red(node.left) and self._is_red(node.left.left):
            node = self._rotate_right(node)
        if self._is_red(node.left) and self._is_red(node.right):
            self._flip_color(node)

        return node