2026-rff_mp/groshevava/docs/data/bst.py

153 lines
4.7 KiB
Python
Raw Normal View History

#реализация справочника на основе бинарного дерева поиска (BST).
#создаём узел
def bst_create_node(name, phone):
return {
'name': name,
'phone': phone,
'left': None,
'right': None
}
#Вставляет запись в BST или обновляет.Возвращает корень дерева
def bst_insert(root, name, phone):
new_node = bst_create_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
#ищет запись в BST по имени. Возвращает телефон или None
def bst_find(root, name):
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_find_min(node):
current = node
while current['left'] is not None:
current = current['left']
return current
#удаляет запись из BST по имени. Возвращает новый корень дерева
def bst_delete(root, name):
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 and current['right'] is None:
if parent is None:
return None
elif parent['left'] == current:
parent['left'] = None
else:
parent['right'] = None
return root
if current['left'] is None:
if parent is None:
return current['right']
elif parent['left'] == current:
parent['left'] = current['right']
else:
parent['right'] = current['right']
return root
if current['right'] is None:
if parent is None:
return current['left']
elif parent['left'] == current:
parent['left'] = current['left']
else:
parent['right'] = current['left']
return root
successor_parent = current
successor = current['right']
while successor['left'] is not None:
successor_parent = successor
successor = successor['left']
current['name'] = successor['name']
current['phone'] = successor['phone']
if successor_parent == current:
successor_parent['right'] = successor['right']
else:
successor_parent['left'] = successor['right']
return root
#рекурсивно собирает записи дерева по возрастанию имён
def _bst_in_order_collect(node, records):
if node is not None:
_bst_in_order_collect(node['left'], records)
records.append((node['name'], node['phone']))
_bst_in_order_collect(node['right'], records)
#отсортированный список всех записей
def bst_list_all(root):
records = []
# Для очень глубоких деревьев лучше использовать итеративный обход
_bst_in_order_iterative(root, records)
return records
#центрированный обход дерева.
def _bst_in_order_iterative(root, records):
stack = []
current = root
while current is not None or len(stack) > 0:
# доходим до самого левого узла
while current is not None:
stack.append(current)
current = current['left']
# обрабатываем узел
current = stack.pop()
records.append((current['name'], current['phone']))
#переходим к правому поддереву
current = current['right']