2026-rff_mp/MylnikovAS/task_1/docs/data/ll_ht_bst.py

153 lines
4.6 KiB
Python
Raw Normal View History

import csv
import random
import sys
import time
import threading
sys.setrecursionlimit(30000)
threading.stack_size(64*1024*1024)
def ll_insert(head, name, phone):
"""Добавляет запись или обновляет телефон, если имя уже существует. Возвращает новую голову списка."""
curr = head
while curr is not None:
if curr["name"] == name:
curr["phone"] = phone
return head
curr = curr["next"]
new_node = {"name": name, "phone": phone, "next": head}
return new_node
def ll_find(head, name):
"""Ищет узел по имени. Возвращает телефон или None."""
curr = head
while curr is not None:
if curr["name"] == name:
return curr["phone"]
curr = curr["next"]
return None
def ll_delete(head, name):
"""Удаляет узел по имени. Возвращает новую голову списка."""
curr = head
prev = None
while curr is not None:
if curr["name"] == name:
if prev is None:
return curr["next"]
else:
prev["next"] = curr["next"]
return head
prev = curr
curr = curr["next"]
return head
def ll_list_all(head):
"""Собирает все записи в список и сортирует их по имени."""
records = []
curr = head
while curr is not None:
records.append((curr["name"], curr["phone"]))
curr = curr["next"]
records.sort(key=lambda x: x[0])
return records
def ht_create(size=1000):
"""Создает пустую хеш-таблицу заданного размера."""
return [None] * size
def ht_insert(buckets, name, phone):
"""Вычисляет индекс бакета и вызывает ll_insert."""
idx = abs(hash(name)) % len(buckets)
buckets[idx] = ll_insert(buckets[idx], name, phone)
def ht_find(buckets, name):
"""Вычисляет индекс бакета и вызывает ll_find."""
idx = abs(hash(name)) % len(buckets)
return ll_find(buckets[idx], name)
def ht_delete(buckets, name):
"""Вычисляет индекс бакета и вызывает ll_delete."""
idx = abs(hash(name)) % len(buckets)
buckets[idx] = ll_delete(buckets[idx], name)
def ht_list_all(buckets):
"""Собирает записи из всех бакетов и сортирует их по имени."""
records = []
for head in buckets:
curr = head
while curr is not None:
records.append((curr["name"], curr["phone"]))
curr = curr["next"]
records.sort(key=lambda x: x[0])
return records
def bst_insert(root, name, phone):
"""Рекурсивно вставляет узел или обновляет телефон."""
if root is None:
return {"name": name, "phone": phone, "left": None, "right": None}
if name == root["name"]:
root["phone"] = phone
elif name < root["name"]:
root["left"] = bst_insert(root["left"], name, phone)
else:
root["right"] = bst_insert(root["right"], name, phone)
return root
def bst_find(root, name):
"""Рекурсивный поиск по дереву."""
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 bst_delete(root, name):
"""Рекурсивное удаление узла из BST."""
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"]
if root["right"] is None:
return root["left"]
min_node = root["right"]
while min_node["left"] is not None:
min_node = min_node["left"]
root["name"] = min_node["name"]
root["phone"] = min_node["phone"]
root["right"] = bst_delete(root["right"], min_node["name"])
return root
def bst_list_all(root):
"""Центрированный обход дерева для сбора записей."""
records = []
def _inorder(node):
if node is not None:
_inorder(node["left"])
records.append((node["name"], node["phone"]))
_inorder(node["right"])
_inorder(root)
return records