# Task 1 import time import random import csv from collections import defaultdict def ll_insert(head, name, phone): new = {'name': name, 'phone': phone, 'next': None} if head is None: return new cur = head while cur: if cur['name'] == name: cur['phone'] = phone return head if cur['next'] is None: break cur = cur['next'] cur['next'] = new return head def ll_find(head, name): cur = head while cur: if cur['name'] == name: return cur['phone'] cur = cur['next'] return None def ll_delete(head, name): if head is None: return None if head['name'] == name: return head['next'] prev = head cur = head['next'] while cur: if cur['name'] == name: prev['next'] = cur['next'] return head prev = cur cur = cur['next'] return head def ll_list_all(head): rec = [] cur = head while cur: rec.append((cur['name'], cur['phone'])) cur = cur['next'] rec.sort(key=lambda x: x[0]) return rec # 2. Хеш-таблица 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): rec = [] for b in buckets: cur = b while cur: rec.append((cur['name'], cur['phone'])) cur = cur['next'] rec.sort(key=lambda x: x[0]) return rec def bst_insert(root, name, phone): new = {'name': name, 'phone': phone, 'left': None, 'right': None} if root is None: return new cur = root while True: if name < cur['name']: if cur['left'] is None: cur['left'] = new break cur = cur['left'] elif name > cur['name']: if cur['right'] is None: cur['right'] = new break cur = cur['right'] else: cur['phone'] = phone break return root def bst_find(root, name): cur = root while cur: if name == cur['name']: return cur['phone'] elif name < cur['name']: cur = cur['left'] else: cur = cur['right'] return None def bst_delete(root, name): if root is None: return None parent = None cur = root while cur and cur['name'] != name: parent = cur if name < cur['name']: cur = cur['left'] else: cur = cur['right'] if cur is None: return root # нет детей if cur['left'] is None and cur['right'] is None: if parent is None: return None if parent['left'] is cur: parent['left'] = None else: parent['right'] = None return root # один ребёнок if cur['left'] is None: child = cur['right'] elif cur['right'] is None: child = cur['left'] else: # два ребёнка ищем минимальный в правом поддереве succ_parent = cur succ = cur['right'] while succ['left']: succ_parent = succ succ = succ['left'] cur['name'], cur['phone'] = succ['name'], succ['phone'] if succ_parent['left'] is succ: succ_parent['left'] = succ['right'] else: succ_parent['right'] = succ['right'] return root if parent is None: return child if parent['left'] is cur: parent['left'] = child else: parent['right'] = child return root def bst_list_all(root): res = [] stack = [] cur = root while stack or cur: while cur: stack.append(cur) cur = cur['left'] cur = stack.pop() res.append((cur['name'], cur['phone'])) cur = cur['right'] return res def gen_data(N=10000): data = [] for i in range(N): name = f"user_{i:06d}" phone = f"+7-{random.randint(100,999)}-{random.randint(100,999)}-{random.randint(1000,9999)}" data.append((name, phone)) shuffled = data[:] random.shuffle(shuffled) sorted_data = sorted(data, key=lambda x: x[0]) return shuffled, sorted_data # 5 повторений сохраняем все замеры def run_test(init_func, ins_func, find_func, del_func, list_func, shuffled, sorted_data, exist_names, missing_names, del_names): rows = [] for order, dataset in [('shuffled', shuffled), ('sorted', sorted_data)]: for rep in range(5): s = init_func() # вставка t1 = time.perf_counter() for name, phone in dataset: s = ins_func(s, name, phone) t2 = time.perf_counter() rows.append([order, rep+1, 'insert', t2 - t1]) # поиск t1 = time.perf_counter() for name in exist_names: find_func(s, name) for name in missing_names: find_func(s, name) t2 = time.perf_counter() rows.append([order, rep+1, 'find', t2 - t1]) # удаление t1 = time.perf_counter() for name in del_names: s = del_func(s, name) t2 = time.perf_counter() rows.append([order, rep+1, 'delete', t2 - t1]) t1 = time.perf_counter() list_func(s) t2 = time.perf_counter() rows.append([order, rep+1, 'list_all', t2 - t1]) return rows if __name__ == '__main__': N = 10000 print(f"Генерация {N} записей...") shuffled, sorted_data = gen_data(N) exist_names = [name for name, _ in shuffled[:100]] missing_names = [f"none_{i}" for i in range(10)] all_names = [name for name, _ in shuffled] del_names = random.sample(all_names, 50) all_rows = [] # для CSV print("Связный список...") rows = run_test(lambda: None, ll_insert, ll_find, ll_delete, ll_list_all, shuffled, sorted_data, exist_names, missing_names, del_names) for r in rows: all_rows.append(['LinkedList'] + r) print("Хеш-таблица...") rows = run_test(lambda: [None]*2000, ht_insert, ht_find, ht_delete, ht_list_all, shuffled, sorted_data, exist_names, missing_names, del_names) for r in rows: all_rows.append(['HashTable'] + r) # бинарное дерево print("Бинарное дерево...") rows = run_test(lambda: None, bst_insert, bst_find, bst_delete, bst_list_all, shuffled, sorted_data, exist_names, missing_names, del_names) for r in rows: all_rows.append(['BST'] + r) # запись в CSV with open('results.csv', 'w', newline='', encoding='utf-8') as f: writer = csv.writer(f) writer.writerow(['Структура', 'Порядок', 'Повторение', 'Операция', 'Время (с)']) writer.writerows(all_rows) print("Все замеры сохранены в results.csv") # Подсчёт и вывод средних avg = defaultdict(list) for row in all_rows: struct, order, rep, op, t = row avg[(struct, order, op)].append(t) print("\nСредние значения (5 запусков):") print(f"{'Структура':<12} {'Порядок':<10} {'Вставка':>10} {'Поиск':>10} {'Удаление':>10} {'ListAll':>10}") for struct in ['LinkedList', 'HashTable', 'BST']: for order in ['shuffled', 'sorted']: row = [struct, order] for op in ['insert', 'find', 'delete', 'list_all']: vals = avg[(struct, order, op)] avg_val = sum(vals)/len(vals) row.append(f"{avg_val:.5f}") print(f"{row[0]:<12} {row[1]:<10} {row[2]:>10} {row[3]:>10} {row[4]:>10} {row[5]:>10}") print("\nГотово!!!!!.")