import time import random import csv import os import matplotlib.pyplot as plt 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['next']: current = current['next'] current['next'] = new_node 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): result = [] current = head while current: result.append((current['name'], current['phone'])) current = current['next'] return sorted(result) def create_hash_table(size=200): return [None] * size def ht_insert(buckets, name, phone): index = hash(name) % len(buckets) buckets[index] = ll_insert(buckets[index], name, phone) def ht_find(buckets, name): index = hash(name) % len(buckets) return ll_find(buckets[index], name) def ht_delete(buckets, name): index = hash(name) % len(buckets) buckets[index] = ll_delete(buckets[index], name) def ht_list_all(buckets): result = [] for bucket in buckets: current = bucket while current: result.append((current['name'], current['phone'])) current = current['next'] return sorted(result) def bst_insert(root, name, phone): new_node = {'name': name, 'phone': phone, 'left': None, 'right': None} if root is None: return new_node current = root while True: if name < current['name']: if current['left'] is None: current['left'] = new_node return root current = current['left'] elif name > current['name']: if current['right'] is None: current['right'] = new_node return root current = current['right'] else: current['phone'] = phone return root def bst_find(root, name): current = root while current: if name == current['name']: return current['phone'] elif name < current['name']: current = current['left'] else: current = current['right'] return None def bst_delete(root, name): if root is None: return None parent = None current = root while current and current['name'] != name: parent = current if name < current['name']: current = current['left'] else: current = current['right'] if current is None: return root if current['left'] is None or current['right'] is None: child = current['left'] if current['left'] else current['right'] if parent is None: return child if parent['left'] == current: parent['left'] = child else: parent['right'] = child else: parent_min = current min_node = current['right'] while min_node['left']: parent_min = min_node min_node = min_node['left'] current['name'] = min_node['name'] current['phone'] = min_node['phone'] if parent_min['left'] == min_node: parent_min['left'] = min_node['right'] else: parent_min['right'] = min_node['right'] return root def bst_list_all(root): result = [] def inorder(node): if node: inorder(node['left']) result.append((node['name'], node['phone'])) inorder(node['right']) inorder(root) return result def generate_records(n=10000): records = [(f"User_{i:05d}", f"8{random.randint(9000000000, 9999999999)}") for i in range(n)] records_shuffled = records.copy() random.shuffle(records_shuffled) records_sorted = sorted(records, key=lambda x: x[0]) return records_shuffled, records_sorted def run_experiments(): random.seed(42) records_shuffled, records_sorted = generate_records(10000) all_results = [] structures = ["LinkedList", "HashTable", "BST"] modes = [("случайный", records_shuffled), ("отсортированный", records_sorted)] for mode_name, records in modes: for struct_name in structures: print(f"Тестируем: {struct_name} | Режим: {mode_name}") for run in range(5): if struct_name == "LinkedList": data = None elif struct_name == "HashTable": data = create_hash_table(200) else: data = None start = time.perf_counter() for name, phone in records: if struct_name == "LinkedList": data = ll_insert(data, name, phone) elif struct_name == "HashTable": ht_insert(data, name, phone) else: data = bst_insert(data, name, phone) insert_time = time.perf_counter() - start test_names = [r[0] for r in random.sample(records, 100)] test_names += [f"None_{i}" for i in range(10)] start = time.perf_counter() for name in test_names: if struct_name == "LinkedList": ll_find(data, name) elif struct_name == "HashTable": ht_find(data, name) else: bst_find(data, name) find_time = time.perf_counter() - start delete_names = [r[0] for r in random.sample(records, 50)] start = time.perf_counter() for name in delete_names: if struct_name == "LinkedList": data = ll_delete(data, name) elif struct_name == "HashTable": ht_delete(data, name) else: data = bst_delete(data, name) delete_time = time.perf_counter() - start all_results.append([struct_name, mode_name, "вставка", run + 1, insert_time]) all_results.append([struct_name, mode_name, "поиск", run + 1, find_time]) all_results.append([struct_name, mode_name, "удаление", run + 1, delete_time]) os.makedirs("docs/data", exist_ok=True) filepath = "docs/data/results.csv" with open(filepath, "w", newline="", encoding="utf-8") as f: writer = csv.writer(f) writer.writerow(["Структура", "Режим", "Операция", "Запуск", "Время (сек)"]) writer.writerows(all_results) print(f"\nРезультаты сохранены в {filepath}") return all_results def plot_results(csv_path="docs/data/results.csv"): import pandas as pd df = pd.read_csv(csv_path) summary = df.groupby(["Структура", "Режим", "Операция"])["Время (сек)"].mean().reset_index() for op in ["вставка", "поиск", "удаление"]: op_data = summary[summary["Операция"] == op] plt.figure(figsize=(10, 6)) x_labels = [] y_values = [] for _, row in op_data.iterrows(): label = f"{row['Структура']}\n({row['Режим']})" x_labels.append(label) y_values.append(row["Время (сек)"]) plt.bar(x_labels, y_values, color=['#4C72B0', '#55A868', '#C44E52'] * 2) plt.title(f"Среднее время операции: {op}") plt.ylabel("Время (сек)") plt.xticks(rotation=45) plt.tight_layout() plt.savefig(f"docs/data/graph_{op}.png") print(f"График сохранён: docs/data/graph_{op}.png") if __name__ == "__main__": run_experiments() plot_results()