diff --git a/skorohodovsa/task_1/binary_tree.py b/skorohodovsa/task_1/binary_tree.py index ab8f633..e95147e 100644 --- a/skorohodovsa/task_1/binary_tree.py +++ b/skorohodovsa/task_1/binary_tree.py @@ -1,73 +1,136 @@ -from typing import Any, Callable +class BSTNode: + def __init__(self, name: str, phone: str): + self.name = name + self.phone = phone + self.left = None + self.right = None -def bst_create_node(name: str, phone: str, left: dict = None, right: dict = None) -> dict: - return { - 'name': name, - 'phone': phone, - 'left': left, - 'right': right - } - - -def comparison_name(name_main: str, name_second: str) -> str: - """Сравнение аргументов - - :param name_main: - :type name_main: str - :param name_second: _description_ - :type name_second: str - :return: _description_ - :rtype: str - """ - return 'right' if name_main >= name_second else 'left' - - -def bst_insert(root: dict, name: str, phone: str) -> dict: - if root is None: - return bst_create_node(name, phone) +class BinarySearchTree: + def __init__(self): + self.root = None - path = comparison_name(root['name'], name) - root[path] = bst_insert(root[path], name, phone) - - return root - - -def bst_create_tree(data: list[dict]) -> dict: - if data is None or len(data) == 0: - raise ValueError("Список пустой!") - base = bst_create_node(**data[0]) - - for var in data[1:]: - bst_insert(base, **var) - - return base - - -def bst_find(root: dict, name: str) -> str | None: - if root is None: - return None - - if root['name'] == name: - return root['phone'] - - path = comparison_name(root['name'], name) - return bst_find(root[path], name) - - -def bst_delete(root, name: str, delete_node: bool = False) -> Any: - if root is None: - return None - - if root['name'] == name: - if delete_node: - root + def insert(self, name: str, phone: str) -> None: + if self.root is None: + self.root = BSTNode(name, phone) else: - pass + self._insert_recursive(self.root, name, phone) - path = comparison_name(root['name'], name) - return bst_find(root[path], name) - - -def bst_list_all(root: dict) -> list[dict]: - pass \ No newline at end of file + 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 \ No newline at end of file