[1] Добавлено binary_tree.py
This commit is contained in:
parent
e45f8cba64
commit
33c3f109fd
|
|
@ -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
|
||||
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
|
||||
Loading…
Reference in New Issue
Block a user