2026-rff_mp/nikolaevda/task1/Zadanie1.py

296 lines
8.5 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.

def ll_insert(head, name, phone):
"""
проходит до конца (или сразу добавляет в конец)
возвращает новую голову (если вставка в начало) или изменяет список по ссылке.
"""
new_node = {'name': name, 'phone': phone, 'next': None}
# в случае пустого списка, новый узел становится головой
if head is None:
return new_node
# в противном случае проходим в конец списка
current = head
while current['next'] is not None:
if current['name'] == name:
current['phone'] = phone
return head
current = current['next']
# проверяем последний узел
if current['name'] == name:
current['phone'] = phone
else:
current['next'] = new_node
return head
def ll_find(head, name):
"""
ищет узел по имени.
возвращает телефон или None
"""
current = head
while current is not None:
if current['name'] == name:
return current['phone']
current = current['next']
return None
def ll_delete(head, name):
"""
удаляет узел по имени.
возвращает новую голову.
"""
# если список пуст
if head is None:
return None
# если удаляем голову
if head['name'] == name:
new_head = head['next']
head['next'] = None
return new_head
# ищем узел для удаления
current = head
while current['next'] is not None:
if current['next']['name'] == name:
target = current['next']
current['next'] = target['next']
target['next'] = None # разрываем связь у удаляемого узла (иными словами, обнуление ссылки)
return head
current = current['next']
return head
def ll_collect(head, result_list):
"""собирает все данные из связного списка в result_list"""
current = head
while current is not None:
result_list.append((current['name'], current['phone']))
current = current['next']
def ll_list_all(head):
"""
собирает все записи в список и сортирует
"""
result = []
current = head
while current is not None:
result.append((current['name'], current['phone']))
current = current['next']
# ручная сортировка пузырьком
n = len(result)
for i in range(n):
for j in range(0, n - i - 1):
if result[j][0] > result[j + 1][0]:
result[j], result[j + 1] = result[j + 1], result[j]
return result
def hash_table(size):
"""создание хеш-таблицы"""
return [None] * size
def hash_func(name, buckets_count):
"""
использует умножение на простое число для лучшего распределения
"""
h = 0
multiplier = 1
for char in name:
h = (h + ord(char) * multiplier) % buckets_count
multiplier = (multiplier * 31) % buckets_count
return h
def ht_insert(buckets, name, phone):
"""добавить или обновить запись"""
if buckets is None:
return
index = hash_func(name, len(buckets))
buckets[index] = ll_insert(buckets[index], name, phone)
def ht_find(buckets, name):
"""найти телефон по имени"""
idx = hash_func(name, len(buckets))
return ll_find(buckets[idx], name)
def ht_delete(buckets, name):
"""
удалить запись
"""
idx = hash_func(name, len(buckets))
buckets[idx] = ll_delete(buckets[idx], name)
def bubble_sort(records):
"""пузырьковая сортировка"""
n = len(records)
for i in range(n - 1):
swapped = False
for j in range(n - 1 - i):
if records[j][0] > records[j + 1][0]:
records[j], records[j + 1] = records[j + 1], records[j]
swapped = True
if not swapped:
break
return records
def ht_list_all(buckets):
"""
собрание всех записей и сортировка
"""
# Собираем все записи
full_data = []
for head in buckets:
ll_collect(head, full_data)
# Сортируем пузырьком
bubble_sort(full_data)
return full_data
#Hash_table1 = hash_table(3)
#ht_insert(Hash_table1, 'Alena', '010')
#ht_insert(Hash_table1, 'Helena', '111')
#ht_insert(Hash_table1, 'Gena', '222')
#print(ht_list_all(Hash_table1))
def bst_insert(root, name, phone):
"""
рекурсивная вставка или обновление записи
возвращает новый корень (если корень меняется)
"""
# если дерево пусто, создаём новый узел
if root is None:
return {'name': name, 'phone': phone, 'left': None, 'right': None}
# вставка в левое поддерево
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):
"""
рекурсивный поиск телефона по имени
возвращает phone или None
"""
# не нашли
if root is None:
return None
# нашли
if root['name'] == name:
return root['phone']
# ищем в левом поддереве
elif name < root['name']:
return bst_find(root['left'], name)
# ищем в правом поддереве
else:
return bst_find(root['right'], name)
def bst_find_min(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 and root['right'] is None:
return None
elif root['left'] is None:
return root['right']
elif root['right'] is None:
return root['left']
# находим минимальный элемент в правом поддереве
successor = bst_find_min(root['right'])
# копируем данные из преемника в текущий узел
root['name'] = successor['name']
root['phone'] = successor['phone']
# удаляем преемника
root['right'] = bst_delete(root['right'], successor['name'])
return root
def bst_list_all(root, result=None):
"""
центрированный (in-order) обход дерева
рекурсивно собирает записи в отсортированном порядке
"""
if result is None:
result = []
if root is not None:
# сначала обходим левое поддерево (все меньшие ключи)
bst_list_all(root['left'], result)
# затем текущий узел
result.append((root['name'], root['phone']))
# затем правое поддерево (все большие ключи)
bst_list_all(root['right'], result)
return result