2026-rff_mp/KislyuninED/docks/data/1-st-exercize/main.py

217 lines
5.4 KiB
Python

# phonebook.py
# Узел списка: {'n': имя, 'p': телефон, 'nxt': следующий}
def ll_insert(head, name, phone):
# обновление, если уже есть
curr = head
while curr is not None:
if curr['n'] == name:
curr['p'] = phone
return head
curr = curr['nxt']
# вставка в начало (новый узел становится головой)
new_node = {'n': name, 'p': phone, 'nxt': head}
return new_node
def ll_find(head, name):
curr = head
while curr is not None:
if curr['n'] == name:
return curr['p']
curr = curr['nxt']
return None
def ll_delete(head, name):
if head is None:
return None
if head['n'] == name:
return head['nxt']
prev = head
curr = head['nxt']
while curr is not None:
if curr['n'] == name:
prev['nxt'] = curr['nxt']
return head
prev = curr
curr = curr['nxt']
return head
def ll_list_all(head):
records = []
curr = head
while curr is not None:
records.append((curr['n'], curr['p']))
curr = curr['nxt']
records.sort(key=lambda x: x[0])
return records
# хеш-функция: сумма ord(name) % size
def _hash(name, size):
h = 0
for ch in name:
h += ord(ch)
return h % size
SIZE = 13 # фиксированный размер таблицы
def ht_create():
return [None] * SIZE
def ht_insert(buckets, name, phone):
idx = _hash(name, len(buckets))
buckets[idx] = ll_insert(buckets[idx], name, phone)
return buckets
def ht_find(buckets, name):
idx = _hash(name, len(buckets))
return ll_find(buckets[idx], name)
def ht_delete(buckets, name):
idx = _hash(name, len(buckets))
buckets[idx] = ll_delete(buckets[idx], name)
return buckets
def ht_list_all(buckets):
all_records = []
for head in buckets:
curr = head
while curr:
all_records.append((curr['n'], curr['p']))
curr = curr['nxt']
all_records.sort(key=lambda x: x[0])
return all_records
# Узел дерева: {'n': имя, 'p': телефон, 'l': левый, 'r': правый}
def bst_create_node(name, phone):
return {'n': name, 'p': phone, 'l': None, 'r': None}
def bst_insert(root, name, phone):
if root is None:
return bst_create_node(name, phone)
# итеративная вставка (без рекурсии)
parent = None
cur = root
while cur:
parent = cur
if name == cur['n']:
cur['p'] = phone
return root
elif name < cur['n']:
cur = cur['l']
else:
cur = cur['r']
# вставляем как лист
if name < parent['n']:
parent['l'] = bst_create_node(name, phone)
else:
parent['r'] = bst_create_node(name, phone)
return root
def bst_find(root, name):
cur = root
while cur:
if name == cur['n']:
return cur['p']
elif name < cur['n']:
cur = cur['l']
else:
cur = cur['r']
return None
def _bst_min(node):
while node['l']:
node = node['l']
return node
def bst_delete(root, name):
if root is None:
return None
# поиск узла и родителя
parent = None
cur = root
while cur and cur['n'] != name:
parent = cur
if name < cur['n']:
cur = cur['l']
else:
cur = cur['r']
if cur is None:
return root
# случай 0 или 1 ребёнок
if cur['l'] is None or cur['r'] is None:
child = cur['l'] if cur['l'] else cur['r']
if parent is None:
return child
if parent['l'] == cur:
parent['l'] = child
else:
parent['r'] = child
else:
# два ребёнка - ищем inorder-преемника
succ_parent = cur
succ = cur['r']
while succ['l']:
succ_parent = succ
succ = succ['l']
cur['n'], cur['p'] = succ['n'], succ['p']
if succ_parent['l'] == succ:
succ_parent['l'] = succ['r']
else:
succ_parent['r'] = succ['r']
return root
def bst_list_all(root):
result = []
def inorder(node):
if node:
inorder(node['l'])
result.append((node['n'], node['p']))
inorder(node['r'])
inorder(root)
return result
# TESTING
if __name__ == '__main__':
print("=== Linked list test ===")
head = None
head = ll_insert(head, "Ivan", "111")
head = ll_insert(head, "Anna", "222")
head = ll_insert(head, "Ivan", "333")
print(ll_find(head, "Ivan")) # 333
print(ll_list_all(head)) # [('Anna','222'),('Ivan','333')]
head = ll_delete(head, "Anna")
print(ll_list_all(head)) # [('Ivan','333')]
print("\n=== Hash table test ===")
buckets = ht_create()
ht_insert(buckets, "Ivan", "111")
ht_insert(buckets, "Boris", "444")
print(ht_find(buckets, "Ivan")) # 111
print(ht_list_all(buckets)) # [('Boris','444'),('Ivan','111')]
print("\n=== BST test ===")
root = None
root = bst_insert(root, "Ivan", "111")
root = bst_insert(root, "Anna", "222")
root = bst_insert(root, "Ivan", "333")
print(bst_find(root, "Ivan")) # 333
print(bst_list_all(root)) # [('Anna','222'),('Ivan','333')]