2026-rff_mp/soldatkinao/lab1/task-1.py

175 lines
5.6 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.

# 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 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):
"""
Возвращает список строк для CSV:
[порядок, повторение, операция, время]
"""
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)
# Запись в 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']:
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Готово (ну почти))).")