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)
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
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
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
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)
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
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