2026-rff_mp/YanyaevAA/task1/[1].py

256 lines
9.2 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
from pathlib import Path
import random
import csv
import sys
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sys.setrecursionlimit(12000)
#Связный список
def ll_insert(head, name, phone):
current = head
while current:
if current['name'] == name:
current['phone'] = phone
return head
current = current['next']
new_node = {'name': name, 'phone': phone, 'next': None}
new_node['next'] = head
return new_node
def ll_find(head, name):
current = head
while current:
if current['name'] == name:
return current['phone']
current = current['next']
return None
def ll_delete(head, name):
if head['name'] == name:
return head['next']
current = head
while current['next']:
if current['next']['name'] == name:
current['next'] = current['next']['next']
break
current = current['next']
return head
def ll_list_all(head):
data= []
current = head
while current:
data.append((current['name'], current['phone']))
current = current['next']
return sorted(data)
#хэш-таблица
def ht_insert(buckets, name, phone):
id=hash(name)%len(buckets)
buckets[id] = ll_insert(buckets[id], name, phone)
def ht_find(buckets, name):
id= hash(name)%len(buckets)
return ll_find(buckets[id], name)
def ht_delete(buckets, name):
id= hash(name)%len(buckets)
buckets[id] = ll_delete(buckets[id], name)
def ht_list_all(buckets):
data = []
for head in buckets:
current = head
while current:
data.append((current['name'], current['phone']))
current = current['next']
return sorted(data)
#Двоичное дерево поиска
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 root['name'] == name:
return root['phone']
elif name<root['name']:
return bst_find(root['left'], name)
else:
return bst_find(root['right'], name)
def minimum(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 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']
elif root['right'] is None:
return root['left']
min=minimum(root['right'])
root['name']=min['name']
root['phone']=min['phone']
root['right']=bst_delete(root['right'], min['name'])
return root
def bst_list_all(root):
result=[]
if root:
result.extend(bst_list_all(root['left']))
result.append((root['name'], root['phone']))
result.extend(bst_list_all(root['right']))
return result
#1. Генерация тестовых данных
def generate(n=10000):
records = [(f"User_{i:05d}", f"+7 ({random.randint(100, 999)}) {random.randint(100, 999)}-{random.randint(00, 99):02}-{random.randint(00, 99):02}") for i in range(n)]
records_sorted =records.copy()
records_shuffled=records.copy()
random.shuffle(records_shuffled)
return records_sorted, records_shuffled
#3.Проведение замеров
#А. Вставка всех записей
def task_A(structure_name, data):
start =time.perf_counter()
if structure_name=="LinkedList":
head=None
for name, phone in data:
head = ll_insert(head, name, phone)
container=head
elif structure_name=="HashTable":
buckets=[None]*1000
for name, phone in data:
ht_insert(buckets, name, phone)
container=buckets
elif structure_name=="BinarySearchTree":
root=None
for name, phone in data:
root = bst_insert(root, name, phone)
container=root
end = time.perf_counter()
elapsed = end - start
return elapsed, container
#Б. Поиск 100 случайных записей
def task_B(structure_name,container, data):
start=time.perf_counter()
if structure_name=="LinkedList":
for name in data:
ll_find(container, name)
elif structure_name=="HashTable":
for name in data:
ht_find(container, name)
elif structure_name=="BinarySearchTree":
for name in data:
bst_find(container, name)
end=time.perf_counter()
elapsed = end - start
return elapsed
#В. Удаление 50 случайных чисел
def task_C(structure_name,container, data):
start=time.perf_counter()
if structure_name=="LinkedList":
for name in data:
container=ll_delete(container, name)
elif structure_name=="HashTable":
for name in data:
ht_delete(container, name)
elif structure_name=="BinarySearchTree":
for name in data:
container = bst_delete(container, name)
end=time.perf_counter()
elapsed = end - start
return elapsed
results=[["Структура", "Режим", "Операция", "Время (сек)"]]
structures_name=["LinkedList", "HashTable", "BinarySearchTree"]
experiment_name=["Вставка", "Поиск", "Удаление"]
mode_of_data=["Случайный", "Отсортированный"]
records_sorted, records_shuffled = generate()
container_shuffled=[]#хранилище структур со случайными данными
container_sorted=[]#хранилище структур с отсортированными данными
names=[record[0] for record in records_shuffled]
#Данные для задания Б
random_names=random.sample(names, 100)
missing_names=[f"None_{i}" for i in range(10)]
names_for_test=random_names+missing_names
#Данные для задания В
names_to_delete=random.sample(names,50)
for i in range(3):
container_shuffled.append(task_A(structures_name[i], records_shuffled)[1])
container_sorted.append(task_A(structures_name[i], records_sorted)[1])
for j in range(5):
# Реализация задания А
result_shuffled = task_A(structures_name[i], records_shuffled)[0]
results.append([structures_name[i], mode_of_data[0], experiment_name[0], result_shuffled])
result_sorted= task_A(structures_name[i], records_sorted)[0]
results.append([structures_name[i], mode_of_data[1], experiment_name[0], result_sorted])
print(f"{structures_name[i]}: Время вставки всех записей {mode_of_data[0]}: {result_shuffled} {mode_of_data[1]}: {result_sorted}")
# Реализация задания Б
result_shuffled = task_B(structures_name[i], container_shuffled[i], names_for_test)
results.append([structures_name[i], mode_of_data[0], experiment_name[1], result_shuffled])
result_sorted = task_B(structures_name[i], container_sorted[i], names_for_test)
results.append([structures_name[i], mode_of_data[1], experiment_name[1], result_sorted])
print(f"{structures_name[i]}: Время нахождения 110 записей для {mode_of_data[0]}: {result_shuffled} {mode_of_data[1]}: {result_sorted} ")
#Реализация задания В
shuffled = container_shuffled[i]
sorted = container_sorted[i]
result_shuffled = task_C(structures_name[i], shuffled, names_to_delete)
results.append([structures_name[i], mode_of_data[0], experiment_name[2], result_shuffled])
result_sorted = task_C(structures_name[i], sorted, names_to_delete)
results.append([structures_name[i], mode_of_data[1], experiment_name[2], result_sorted])
print(f"{structures_name[i]}: Время удаления 50 записей для {mode_of_data[0]}: {result_shuffled} {mode_of_data[1]}: {result_sorted}")
#4. Сохранение результатов\
current_dir=Path.cwd()
target=current_dir.parent/"docs"/"data"
csv_file=target /"results.csv"
with open(csv_file, "w", newline="",encoding="utf-8-sig") as f:
writer = csv.writer(f)
writer.writerows(results)
#Построение графиков
df = pd.read_csv(csv_file)
df_avg = df.groupby(["Структура", "Режим", "Операция"])["Время (сек)"].mean().reset_index()
fig, axes = plt.subplots(1, 3, figsize=(18, 6), sharey=True)
for i, experiment in enumerate(experiment_name):
data_experiment = df_avg[df_avg["Операция"] == experiment]
sns.barplot(ax=axes[i],data=data_experiment, x="Структура",y="Время (сек)",hue="Режим")
axes[i].set_title(experiment)
axes[i].set_ylabel("Среднее время (сек)")
axes[i].set_yscale("log")
plt.tight_layout()
png_file= target/"graphics.png"
plt.savefig(png_file, dpi=300, bbox_inches='tight')
plt.show()