2026-rff_mp/SimonovaMS/phonebook_1_2.py
2026-03-15 18:54:31 +03:00

266 lines
7.3 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.

import time
import csv
import random
from functools import lru_cache
from operator import index
#LinkedListPhoneBook
def create_node(name, phone):
return {'name': name, 'phone': phone, 'next': None}
def ll_insert(head, name, phone):
new_node = create_node(name,phone)
if head is None:
return new_node
# if head['name'] == name:
# new_node['next']=head['next']
# return new_node
current = head
while current['next'] is not None:
if current['next']['name'] == name:
new_node['next'] = current['next']['next']
current['next']=new_node
return head
current=current['next']
current['next'] = new_node
return head
def ll_find(head, name):
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:
return head['next']
current =head
while current['next'] is not None:
if current['next']['name'] == name:
current['next'] = current['next']['next']
return head
current=current['next']
return head
def ll_list_all(head):
records = []
current = head
while current is not None:
records.append((current['name'], current['phone']))
current = current['next']
records.sort(key=lambda x: x[0])
return records
#хеш=тфблица
def create_buckets(size=1000):
return [None] * size
def hash_function(name, buckest_size):
hash_value = 0
for char in name:
hash_value = (hash_value * 31 + ord(char)) % buckest_size
return hash_value
def ht_insert(buckets, name, phone):
index = hash_function(name, len(buckets))
buckets[index] = ll_insert(buckets[index], name, phone)
def ht_find(buckets, name):
index = hash_function(name, len(buckets))
return ll_find(buckets[index], name)
def ht_delete(buckets, name):
index = hash_function(name, len(buckets))
buckets[index] = ll_delete(buckets[index], name)
def ht_list_all(buckets):
records = []
for bucket in buckets:
current = bucket
while current is not None:
records.append((current['name'], current['phone']))
current = current['next']
records.sort(key=lambda x:x[0])
return records
#bts
def create_bst_node(name, phone):
return {'name': name, 'phone': phone, 'left': None, 'right': None}
def bst_insert(root, name, phone):
new_node = create_bst_node(name, phone)
if root is None:
return new_node
current = root
while True:
if name == current['name']:
current['phone'] = phone
return root
elif name < current['name']:
if current['left'] is None:
current['left'] = new_node
return root
current = current['left']
else:
if current['right'] is None:
current['right'] = new_node
return root
current = current['right']
def bst_find(root, name):
# if root is None:
# return None
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
def bst_delete(root, name):
"""ИТЕРАТИВНОЕ удаление (без рекурсии)"""
if root is None:
return None
# Специальный случай: удаляем корень
if root['name'] == name:
# Нет потомков
if root['left'] is None and root['right'] is None:
return None
# Только правый потомок
if root['left'] is None:
return root['right']
# Только левый потомок
if root['right'] is None:
return root['left']
# Есть оба потомка
# Находим минимальный узел в правом поддереве
parent = root
min_node = root['right']
while min_node['left']:
parent = min_node
min_node = min_node['left']
# Копируем данные
root['name'] = min_node['name']
root['phone'] = min_node['phone']
# Удаляем минимальный узел
if parent == root:
parent['right'] = min_node['right']
else:
parent['left'] = min_node['right']
return root
# Ищем узел для удаления и его родителя
parent = None
current = root
while current and current['name'] != name:
parent = current
if name < current['name']:
current = current['left']
else:
current = current['right']
# Если не нашли
if current is None:
return root
# Случай 1: нет потомков
if current['left'] is None and current['right'] is None:
if parent['left'] == current:
parent['left'] = None
else:
parent['right'] = None
# Случай 2: только правый потомок
elif current['left'] is None:
if parent['left'] == current:
parent['left'] = current['right']
else:
parent['right'] = current['right']
# Случай 3: только левый потомок
elif current['right'] is None:
if parent['left'] == current:
parent['left'] = current['left']
else:
parent['right'] = current['left']
# Случай 4: есть оба потомка
else:
# Находим минимальный узел в правом поддереве
min_parent = current
min_node = current['right']
while min_node['left']:
min_parent = min_node
min_node = min_node['left']
# Копируем данные
current['name'] = min_node['name']
current['phone'] = min_node['phone']
# Удаляем минимальный узел
if min_parent == current:
min_parent['right'] = min_node['right']
else:
min_parent['left'] = min_node['right']
return root
def bst_list_all(root):
"""Центрированный обход с использованием стека"""
records = []
stack = []
current = root
while stack or current:
while current:
stack.append(current)
current = current['left']
current = stack.pop()
records.append((current['name'], current['phone']))
current = current['right']
return records
def bst_list_all(root):
records =[]
stack = []
current = root
while stack or current is not None:
while current is not None:
stack.append(current)
current=current['left']
current=stack.pop()
records.append((current['name'], current['phone']))
current=current['right']
return records