2026-05-25 07:55:25 +00:00
|
|
|
class BSTNode:
|
|
|
|
|
def __init__(self, name: str, phone: str):
|
|
|
|
|
self.name = name
|
|
|
|
|
self.phone = phone
|
|
|
|
|
self.left = None
|
|
|
|
|
self.right = None
|
2026-05-16 21:04:06 +00:00
|
|
|
|
2026-05-25 07:55:25 +00:00
|
|
|
class BinarySearchTree:
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self.root = None
|
2026-05-16 21:04:06 +00:00
|
|
|
|
2026-05-25 07:55:25 +00:00
|
|
|
def insert(self, name: str, phone: str) -> None:
|
|
|
|
|
if self.root is None:
|
|
|
|
|
self.root = BSTNode(name, phone)
|
2026-05-25 08:27:50 +00:00
|
|
|
return
|
2026-05-25 07:55:25 +00:00
|
|
|
|
2026-05-25 08:27:50 +00:00
|
|
|
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
|
2026-05-16 21:04:06 +00:00
|
|
|
|
2026-05-25 07:55:25 +00:00
|
|
|
def search(self, name: str):
|
2026-05-25 08:27:50 +00:00
|
|
|
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
|
2026-05-16 21:04:06 +00:00
|
|
|
|
2026-05-25 07:55:25 +00:00
|
|
|
def delete(self, name: str) -> bool:
|
2026-05-25 08:27:50 +00:00
|
|
|
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
|
2026-05-25 07:55:25 +00:00
|
|
|
|
2026-05-16 21:04:06 +00:00
|
|
|
else:
|
2026-05-25 08:27:50 +00:00
|
|
|
successor_parent = current
|
|
|
|
|
successor = current.right
|
|
|
|
|
while successor.left:
|
|
|
|
|
successor_parent = successor
|
|
|
|
|
successor = successor.left
|
2026-05-25 07:55:25 +00:00
|
|
|
|
2026-05-25 08:27:50 +00:00
|
|
|
current.name = successor.name
|
|
|
|
|
current.phone = successor.phone
|
2026-05-25 07:55:25 +00:00
|
|
|
|
2026-05-25 08:27:50 +00:00
|
|
|
if successor_parent.left == successor:
|
|
|
|
|
successor_parent.left = successor.right
|
|
|
|
|
else:
|
|
|
|
|
successor_parent.right = successor.right
|
2026-05-25 07:55:25 +00:00
|
|
|
|
2026-05-25 08:27:50 +00:00
|
|
|
return True
|
2026-05-25 07:55:25 +00:00
|
|
|
|
|
|
|
|
def inorder(self) -> list:
|
|
|
|
|
result = []
|
2026-05-25 08:27:50 +00:00
|
|
|
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
|
|
|
|
|
|
2026-05-25 07:55:25 +00:00
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
def get_height(self) -> int:
|
2026-05-25 08:27:50 +00:00
|
|
|
if self.root is None:
|
2026-05-25 07:55:25 +00:00
|
|
|
return 0
|
2026-05-25 08:27:50 +00:00
|
|
|
|
|
|
|
|
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
|
2026-05-25 07:55:25 +00:00
|
|
|
|
|
|
|
|
def get_size(self) -> int:
|
2026-05-25 08:27:50 +00:00
|
|
|
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
|
2026-05-25 07:55:25 +00:00
|
|
|
|
|
|
|
|
def clear(self) -> None:
|
|
|
|
|
self.root = None
|
|
|
|
|
|
|
|
|
|
def is_empty(self) -> bool:
|
|
|
|
|
return self.root is None
|