2026-rff_mp/KuzminskiyAA/Task 1/Dogs/Data/1.py
2026-05-25 00:12:23 +03:00

250 lines
8.7 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 random
import csv
import matplotlib.pyplot as plt
import numpy as np
def ll_insert(head, name, phone):
new_node = {'name': name, 'phone': phone, 'next': None}
if head is None:
return new_node
current = head
while current:
if current['name'] == name:
current['phone'] = phone
return head
if current['next'] is None:
current['next'] = new_node
return head
current = current['next']
return head
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 is None:
return None
if head['name'] == name:
return head['next']
current = head
while current['next']:
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:
records.append((current['name'], current['phone']))
current = current['next']
return sorted(records, key=lambda x: x[0])
def hash_func(name, size):
return sum(ord(c) for c in name) % size
def ht_create(size=1000):
return [None] * size
def ht_insert(table, name, phone):
idx = hash_func(name, len(table))
table[idx] = ll_insert(table[idx], name, phone)
def ht_find(table, name):
idx = hash_func(name, len(table))
return ll_find(table[idx], name)
def ht_delete(table, name):
idx = hash_func(name, len(table))
table[idx] = ll_delete(table[idx], name)
def ht_list_all(table):
records = []
for bucket in table:
current = bucket
while current:
records.append((current['name'], current['phone']))
current = current['next']
return sorted(records, key=lambda x: x[0])
def bst_insert(root, name, phone):
if root is None:
return {'name': name, 'phone': phone, 'left': None, 'right': None}
if name < root['name']:
root['left'] = bst_insert(root['left'], name, phone)
elif name > root['name']:
root['right'] = bst_insert(root['right'], name, phone)
else:
root['phone'] = phone
return root
def bst_find(root, name):
if root is None:
return None
if name == root['name']:
return root['phone']
elif name < root['name']:
return bst_find(root['left'], name)
else:
return bst_find(root['right'], name)
def bst_min(node):
while node and node['left']:
node = node['left']
return node
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']
if root['right'] is None:
return root['left']
min_node = bst_min(root['right'])
root['name'] = min_node['name']
root['phone'] = min_node['phone']
root['right'] = bst_delete(root['right'], min_node['name'])
return root
def bst_list_all(root):
records = []
if root:
records.extend(bst_list_all(root['left']))
records.append((root['name'], root['phone']))
records.extend(bst_list_all(root['right']))
return records
def generate_data(n=2000):
random_data = [(f"User_{i:05d}", str(i)) for i in range(n)]
random.shuffle(random_data)
sorted_data = sorted(random_data, key=lambda x: x[0])
return random_data, sorted_data
def run_test(data, struct_name, create, insert, find, delete):
times = {'insert': [], 'search': [], 'delete': []}
for _ in range(5):
s = create()
start = time.perf_counter()
if struct_name == 'LinkedList' or struct_name == 'BST':
for name, phone in data:
s = insert(s, name, phone)
else:
for name, phone in data:
insert(s, name, phone)
times['insert'].append(time.perf_counter() - start)
names = [random.choice(data)[0] for _ in range(100)] + [f"None_{i}" for i in range(10)]
start = time.perf_counter()
for name in names:
find(s, name)
times['search'].append(time.perf_counter() - start)
del_names = [random.choice(data)[0] for _ in range(50)]
start = time.perf_counter()
for name in del_names:
if struct_name == 'LinkedList' or struct_name == 'BST':
s = delete(s, name)
else:
delete(s, name)
times['delete'].append(time.perf_counter() - start)
return {op: sum(t)/len(t) for op, t in times.items()}
def plot_results(data_matrix):
structures = ['LinkedList', 'HashTable', 'BST']
operations = ['insert', 'search', 'delete']
modes = ['random', 'sorted']
fig, axes = plt.subplots(2, 2, figsize=(14, 12))
x = np.arange(len(structures))
width = 0.25
for i, op in enumerate(operations):
values = [data_matrix[s]['random'][op] for s in structures]
axes[0,0].bar(x + i*width, values, width, label=op)
axes[0,0].set_xlabel('Структура данных')
axes[0,0].set_ylabel('Время (секунды)')
axes[0,0].set_title('Случайный порядок данных')
axes[0,0].set_xticks(x + width, structures)
axes[0,0].legend()
axes[0,0].grid(True, alpha=0.3)
for i, op in enumerate(operations):
values = [data_matrix[s]['sorted'][op] for s in structures]
axes[0,1].bar(x + i*width, values, width, label=op)
axes[0,1].set_xlabel('Структура данных')
axes[0,1].set_ylabel('Время (секунды)')
axes[0,1].set_title('Отсортированный порядок данных')
axes[0,1].set_xticks(x + width, structures)
axes[0,1].legend()
axes[0,1].grid(True, alpha=0.3)
x = np.arange(len(operations))
width = 0.35
for i, mode in enumerate(modes):
values = [data_matrix['BST'][mode][op] for op in operations]
axes[1,0].bar(x + i*width, values, width, label=mode)
axes[1,0].set_xlabel('Операция')
axes[1,0].set_ylabel('Время (секунды)')
axes[1,0].set_title('BST: влияние порядка данных')
axes[1,0].set_xticks(x + width/2, operations)
axes[1,0].legend()
axes[1,0].grid(True, alpha=0.3)
for struct in structures:
times_random = [data_matrix[struct]['random'][op] for op in operations]
times_sorted = [data_matrix[struct]['sorted'][op] for op in operations]
axes[1,1].plot(operations, times_random, marker='o', label=f'{struct} случайный')
axes[1,1].plot(operations, times_sorted, marker='s', linestyle='--', label=f'{struct} отсортированный')
axes[1,1].set_yscale('log')
axes[1,1].set_xlabel('Операция')
axes[1,1].set_ylabel('Время (секунды) - логарифмическая шкала')
axes[1,1].set_title('Сравнение производительности')
axes[1,1].legend()
axes[1,1].grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('performance_graphs.png')
plt.show()
random_data, sorted_data = generate_data(2000)
structs = [
('LinkedList', lambda: None, ll_insert, ll_find, ll_delete),
('HashTable', lambda: ht_create(2000), ht_insert, ht_find, ht_delete),
('BST', lambda: None, bst_insert, bst_find, bst_delete)
]
data_matrix = {'LinkedList': {'random': {}, 'sorted': {}},
'HashTable': {'random': {}, 'sorted': {}},
'BST': {'random': {}, 'sorted': {}}}
for name, create, insert, find, delete in structs:
for order, data in [('random', random_data), ('sorted', sorted_data)]:
times = run_test(data, name, create, insert, find, delete)
data_matrix[name][order] = times
with open('results.csv', 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['структура', 'порядок_данных', 'операция', 'время_секунды'])
for name in ['LinkedList', 'HashTable', 'BST']:
for order in ['random', 'sorted']:
for op in ['insert', 'search', 'delete']:
writer.writerow([name, order, op, data_matrix[name][order][op]])
plot_results(data_matrix)
print("\n РЕЗУЛЬТАТЫ")
for name in ['LinkedList', 'HashTable', 'BST']:
for order in ['random', 'sorted']:
print(f"{name} {order}: вставка={data_matrix[name][order]['insert']:.6f}, поиск={data_matrix[name][order]['search']:.6f}, удаление={data_matrix[name][order]['delete']:.6f}")