119 lines
2.9 KiB
Python
119 lines
2.9 KiB
Python
from typing import Any, Dict, List, Optional
|
|
|
|
|
|
Node = Dict[str, Any]
|
|
|
|
|
|
def _make_node(name: str, phone: str) -> Node:
|
|
return {"name": name, "phone": phone, "left": None, "right": None}
|
|
|
|
|
|
def bst_insert(root: Optional[Node], name: str, phone: str) -> Node:
|
|
new_node = _make_node(name, phone)
|
|
|
|
if root is None:
|
|
return new_node
|
|
|
|
current = root
|
|
parent = None
|
|
|
|
while current is not None:
|
|
parent = current
|
|
if name < current["name"]:
|
|
current = current["left"]
|
|
elif name > current["name"]:
|
|
current = current["right"]
|
|
else:
|
|
current["phone"] = phone
|
|
return root
|
|
|
|
if name < parent["name"]:
|
|
parent["left"] = new_node
|
|
else:
|
|
parent["right"] = new_node
|
|
|
|
return root
|
|
|
|
|
|
def bst_find(root: Optional[Node], name: str) -> Optional[str]:
|
|
current = root
|
|
while current is not None:
|
|
if name < current["name"]:
|
|
current = current["left"]
|
|
elif name > current["name"]:
|
|
current = current["right"]
|
|
else:
|
|
return current["phone"]
|
|
return None
|
|
|
|
|
|
def _find_min_node(node: Node) -> Node:
|
|
current = node
|
|
while current["left"] is not None:
|
|
current = current["left"]
|
|
return current
|
|
|
|
|
|
def bst_delete(root: Optional[Node], name: str) -> Optional[Node]:
|
|
if root is None:
|
|
return None
|
|
|
|
parent = None
|
|
current = root
|
|
|
|
while current is not None and current["name"] != name:
|
|
parent = current
|
|
if name < current["name"]:
|
|
current = current["left"]
|
|
else:
|
|
current = current["right"]
|
|
|
|
if current is None:
|
|
return root
|
|
|
|
if current["left"] is None or current["right"] is None:
|
|
child = current["left"] if current["left"] is not None else current["right"]
|
|
|
|
if parent is None:
|
|
return child
|
|
|
|
if parent["left"] is current:
|
|
parent["left"] = child
|
|
else:
|
|
parent["right"] = child
|
|
return root
|
|
|
|
succ_parent = current
|
|
successor = current["right"]
|
|
while successor["left"] is not None:
|
|
succ_parent = successor
|
|
successor = successor["left"]
|
|
|
|
current["name"] = successor["name"]
|
|
current["phone"] = successor["phone"]
|
|
|
|
successor_child = successor["right"]
|
|
if succ_parent["left"] is successor:
|
|
succ_parent["left"] = successor_child
|
|
else:
|
|
succ_parent["right"] = successor_child
|
|
|
|
return root
|
|
|
|
|
|
def bst_list_all(root: Optional[Node]) -> List[Dict[str, str]]:
|
|
result: List[Dict[str, str]] = []
|
|
stack: List[Node] = []
|
|
current = root
|
|
|
|
while current is not None or stack:
|
|
while current is not None:
|
|
stack.append(current)
|
|
current = current["left"]
|
|
|
|
current = stack.pop()
|
|
result.append({"name": current["name"], "phone": current["phone"]})
|
|
current = current["right"]
|
|
|
|
return result
|