diff --git a/ivanchenkoam/laba1.txt b/ivanchenkoam/laba1.txt index 93e485a..65e4aa7 100644 --- a/ivanchenkoam/laba1.txt +++ b/ivanchenkoam/laba1.txt @@ -103,6 +103,136 @@ def ht_list_all(buckets: List[Optional[Dict]]) -> List[Tuple[str, str]]: records.sort(key=lambda x: x[0]) return records +def bst_insert(root: Optional[Dict], name: str, phone: str) -> Dict: + """Вставка в BST (итеративная)""" + new_node = {'name': name, 'phone': phone, 'left': None, 'right': None} + + if root is None: + return new_node + + current = root + while True: + if name < current['name']: + if current['left'] is None: + current['left'] = new_node + break + else: + current = current['left'] + elif name > current['name']: + if current['right'] is None: + current['right'] = new_node + break + else: + current = current['right'] + else: + # Обновляем существующую запись + current['phone'] = phone + break + + return root + + +def bst_find(root: Optional[Dict], name: str) -> Optional[str]: + """Поиск в BST (итеративный)""" + current = root + while current is not None: + if name == current['name']: + return current['phone'] + elif name < current['name']: + current = current['left'] + else: + current = current['right'] + return None + + +def bst_min_node(node: Dict) -> Dict: + """Поиск узла с минимальным значением""" + current = node + while current['left'] is not None: + current = current['left'] + return current + + +def bst_delete(root: Optional[Dict], name: str) -> Optional[Dict]: + """Удаление из BST (итеративная версия)""" + 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 + + # Случай 1: узел не имеет детей + if current['left'] is None and current['right'] is None: + if parent is None: + return None + if parent['left'] == current: + parent['left'] = None + else: + parent['right'] = None + return root + + # Случай 2: узел имеет одного ребёнка + if current['left'] is None: + child = current['right'] + elif current['right'] is None: + child = current['left'] + else: + # Случай 3: узел имеет двух детей + # Находим минимальный узел в правом поддереве + successor_parent = current + successor = current['right'] + while successor['left'] is not None: + successor_parent = successor + successor = successor['left'] + + # Копируем данные из successor в current + current['name'] = successor['name'] + current['phone'] = successor['phone'] + + # Удаляем successor + if successor_parent['left'] == successor: + successor_parent['left'] = successor['right'] + else: + successor_parent['right'] = successor['right'] + + return root + + # Присоединяем ребёнка к родителю + if parent is None: + return child + if parent['left'] == current: + parent['left'] = child + else: + parent['right'] = child + + return root + + +def bst_inorder(root: Optional[Dict], records: List[Tuple[str, str]]) -> None: + """Центрированный обход BST (рекурсивный)""" + if root is not None: + bst_inorder(root['left'], records) + records.append((root['name'], root['phone'])) + bst_inorder(root['right'], records) + + +def bst_list_all(root: Optional[Dict]) -> List[Tuple[str, str]]: + """Сбор всех записей из BST (уже отсортированы)""" + records = [] + bst_inorder(root, records) + return records + records.sort(key=lambda x: x[0])