2026-rff_mp/src/bst.py

88 lines
2.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# bst.py
# Двоичное дерево поиска по имени
def create_node(name, phone):
"""Создаёт узел дерева."""
return {
'name': name,
'phone': phone,
'left': None,
'right': None
}
def bst_insert(root, name, phone):
"""
Рекурсивно вставляет или обновляет запись.
Возвращает корень (может измениться при первой вставке).
"""
if root is None:
return create_node(name, phone)
if name < root['name']:
root['left'] = bst_insert(root['left'], name, phone)
elif name > root['name']:
root['right'] = bst_insert(root['right'], name, phone)
else: # имя уже существует обновляем телефон
root['phone'] = phone
return root
def bst_find(root, name):
"""Возвращает телефон или None."""
if root is None:
return None
if name == root['name']:
return root['phone']
elif name < root['name']:
return bst_find(root['left'], name)
else:
return bst_find(root['right'], name)
def _min_node(node):
"""Находит узел с минимальным именем в поддереве."""
current = node
while current['left'] is not None:
current = current['left']
return current
def bst_delete(root, name):
"""
Удаляет узел с заданным именем.
Возвращает новый корень поддерева.
"""
if root is None:
return None
if name < root['name']:
root['left'] = bst_delete(root['left'], name)
elif name > root['name']:
root['right'] = bst_delete(root['right'], name)
else:
# Узел найден
if root['left'] is None:
return root['right']
elif root['right'] is None:
return root['left']
# Узел с двумя детьми: находим минимальный в правом поддереве
temp = _min_node(root['right'])
root['name'] = temp['name']
root['phone'] = temp['phone']
root['right'] = bst_delete(root['right'], temp['name'])
return root
def bst_list_all(root):
"""
Центрированный (in-order) обход возвращает записи,
уже отсортированные по имени.
"""
def _inorder(node, result):
if node is None:
return
_inorder(node['left'], result)
result.append((node['name'], node['phone']))
_inorder(node['right'], result)
records = []
_inorder(root, records)
return records