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) return current = self.root while True: if name < current.name: if current.left is None: current.left = BSTNode(name, phone) break current = current.left elif name > current.name: if current.right is None: current.right = BSTNode(name, phone) break current = current.right else: current.phone = phone break def search(self, name: str): current = self.root while current: if name == current.name: return current.phone elif name < current.name: current = current.left else: current = current.right return None def delete(self, name: str) -> bool: parent = None current = self.root while current and current.name != name: parent = current if name < current.name: current = current.left else: current = current.right if current is None: return False if current.left is None and current.right is None: if parent is None: self.root = None elif parent.left == current: parent.left = None else: parent.right = None elif current.left is None: if parent is None: self.root = current.right elif parent.left == current: parent.left = current.right else: parent.right = current.right elif current.right is None: if parent is None: self.root = current.left elif parent.left == current: parent.left = current.left else: parent.right = current.left else: successor_parent = current successor = current.right while successor.left: successor_parent = successor successor = successor.left current.name = successor.name current.phone = successor.phone if successor_parent.left == successor: successor_parent.left = successor.right else: successor_parent.right = successor.right return True def inorder(self) -> list: result = [] stack = [] current = self.root while stack or current: while current: stack.append(current) current = current.left current = stack.pop() result.append({'name': current.name, 'phone': current.phone}) current = current.right return result def get_height(self) -> int: if self.root is None: return 0 queue = [(self.root, 1)] max_height = 0 while queue: node, height = queue.pop(0) max_height = max(max_height, height) if node.left: queue.append((node.left, height + 1)) if node.right: queue.append((node.right, height + 1)) return max_height def get_size(self) -> int: count = 0 stack = [self.root] if self.root else [] while stack: node = stack.pop() count += 1 if node.left: stack.append(node.left) if node.right: stack.append(node.right) return count def clear(self) -> None: self.root = None def is_empty(self) -> bool: return self.root is None