class BSTNode: def __init__(self, name: str, phone: str): self.name = name self.phone = phone self.left = None self.right = None class BinarySearchTree: def __init__(self): self.root = None def insert(self, name: str, phone: str) -> None: if self.root is None: self.root = BSTNode(name, phone) else: self._insert_recursive(self.root, name, phone) def _insert_recursive(self, node: BSTNode, name: str, phone: str) -> BSTNode: if node is None: return BSTNode(name, phone) if name < node.name: node.left = self._insert_recursive(node.left, name, phone) elif name > node.name: node.right = self._insert_recursive(node.right, name, phone) else: node.phone = phone return node def search(self, name: str): return self._search_recursive(self.root, name) def _search_recursive(self, node: BSTNode, name: str): if node is None: return None if name == node.name: return node.phone elif name < node.name: return self._search_recursive(node.left, name) else: return self._search_recursive(node.right, name) def delete(self, name: str) -> bool: self.root, deleted = self._delete_recursive(self.root, name) return deleted def _delete_recursive(self, node: BSTNode, name: str): if node is None: return None, False deleted = False if name < node.name: node.left, deleted = self._delete_recursive(node.left, name) elif name > node.name: node.right, deleted = self._delete_recursive(node.right, name) else: deleted = True if node.left is None and node.right is None: return None, True if node.left is None: return node.right, True if node.right is None: return node.left, True min_node = self._find_min(node.right) node.name = min_node.name node.phone = min_node.phone node.right, _ = self._delete_recursive(node.right, min_node.name) return node, deleted def _find_min(self, node: BSTNode) -> BSTNode: current = node while current.left: current = current.left return current def inorder(self) -> list: result = [] self._inorder_recursive(self.root, result) return result def _inorder_recursive(self, node: BSTNode, result: list) -> None: if node: self._inorder_recursive(node.left, result) result.append({'name': node.name, 'phone': node.phone}) self._inorder_recursive(node.right, result) def preorder(self) -> list: result = [] self._preorder_recursive(self.root, result) return result def _preorder_recursive(self, node: BSTNode, result: list) -> None: if node: result.append({'name': node.name, 'phone': node.phone}) self._preorder_recursive(node.left, result) self._preorder_recursive(node.right, result) def postorder(self) -> list: result = [] self._postorder_recursive(self.root, result) return result def _postorder_recursive(self, node: BSTNode, result: list) -> None: if node: self._postorder_recursive(node.left, result) self._postorder_recursive(node.right, result) result.append({'name': node.name, 'phone': node.phone}) def get_height(self) -> int: return self._height_recursive(self.root) def _height_recursive(self, node: BSTNode) -> int: if node is None: return 0 return 1 + max(self._height_recursive(node.left), self._height_recursive(node.right)) def get_size(self) -> int: return self._size_recursive(self.root) def _size_recursive(self, node: BSTNode) -> int: if node is None: return 0 return 1 + self._size_recursive(node.left) + self._size_recursive(node.right) def clear(self) -> None: self.root = None def is_empty(self) -> bool: return self.root is None