2026-rff_mp/MarkinAM/1/structures.py
2026-05-25 09:57:30 +03:00

198 lines
5.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.

# === 1. Связный список (LinkedList) ===
def ll_insert(head, name, phone):
# Вставка новой записи или обновление существующей
if head is None:
return {'name': name, 'phone': phone, 'next': None}
current = head
# Ищем, есть ли уже запись с этим именем
while current is not None:
if current['name'] == name:
current['phone'] = phone # Обновляем телефон
return head
current = current["next"]
# Если не нашли, добавляем в конец
current = head
while current['next'] is not None:
current = current['next']
current['next'] = {'name': name, 'phone': phone, 'next': None}
return head
def ll_find(head, name):
"""Ищет запись по имени, возвращает телефон или None."""
current = head
while current:
if current['name'] == name:
return current['phone']
current = current['next']
return None
def ll_delete(head, name):
current = head
previous = None
while current is not None:
if current['name'] == name:
if previous is None:
return current['next']
previous['next'] = current['next']
return head
previous = current
current = current['next']
return head
def ll_list_all(head):
#Собирает все записи в отсортированный список кортежей.
records = []
current = head
while current:
records.append((current['name'], current['phone']))
current = current['next']
# Сортируем по имени
return sorted(records, key=lambda x: x[0])
# === 2. Хеш-таблица (HashTable) ===
def my_hash(s, M):
B = 31
n = len(s)
h = 0
for i in range(n):
h += ord(s[i]) * (B ** (n - 1 - i))
return h % M
def ht_insert(buckets, name, phone):
index = my_hash(name, len(buckets))
# Вставляем в соответствующий бакет
buckets[index] = ll_insert(buckets[index], name, phone)
return buckets
def ht_find(buckets, name):
index = my_hash(name, len(buckets))
# Ищем внутри бакета
return ll_find(buckets[index], name)
def ht_delete(buckets, name):
index = my_hash(name, len(buckets))
# Удаляем внутри бакета
buckets[index] = ll_delete(buckets[index], name)
return buckets
def ht_list_all(buckets):
# Собираем все записи из бакетов
result = []
for i in range(len(buckets)):
result += ll_list_all(buckets[i])
# Сортируем по имени
result.sort(key=lambda x: x[0])
return result
# === 3. Двоичное дерево поиска (BST) ===
def bst_insert(root, name, phone):
if root is None:
return {'name': name, 'phone': phone,'left': None, 'right': None}
current = root
while True:
# если такое имя уже есть — меняем телефон
if name == current['name']:
current['phone'] = phone
return root
# если новое имя меньше — идём влево
if name < current['name']:
if current['left'] is None:
current['left'] = {'name': name, 'phone': phone,'left': None, 'right': None}
return root
current = current['left']
# если новое имя больше — идём вправо
else:
if current['right'] is None:
current['right'] = {'name': name, 'phone': phone,'left': None, 'right': None}
return root
current = current['right']
def bst_find(root, name):
current = root
while current is not None:
if name == current['name']:
return current['phone']
if name < current['name']:
current = current['left']
else:
current = current['right']
return None
def bst_delete(root, name):
current = root
previous = None
while current is not None and current['name'] != name:
previous = current
if name < current['name']:
current = current['left']
else:
current = current['right']
# если не нашли
if current is None:
return root
# 2. Если у узла два потомка
if current['left'] is not None and current['right'] is not None:
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
current = successor
previous = successor_parent
#3
if current['left'] is not None:
child = current['left']
else:
child = current['right']
# 4. Если удаляем корень
if previous is None:
return child
# 5. Переподключаем родителя
if previous['left'] is current:
previous['left'] = child
else:
previous['right'] = child
return root
def bst_list_all(root):
result = []
def inorder(node):
if node is None:
return
inorder(node['left'])
result.append((node['name'], node['phone']))
inorder(node['right'])
inorder(root)
return result