from binary_tree import BinarySearchTree from hash_table import HashTable import linked_list as ll import time import random import csv import matplotlib.pyplot as plt import numpy as np def run_experiments(): results = [] results.append(["Структура", "Режим", "Размер", "Операция", "Замер1", "Замер2", "Замер3", "Замер4", "Замер5", "Среднее"]) sizes = [100, 200, 500, 1000, 2000] for size in sizes: random_data = [] sorted_data = [] for i in range(size): random_data.append({"name": f"user_{random.randint(1, 100000)}", "phone": f"123-{i}"}) sorted_data.append({"name": f"user_{i:05d}", "phone": f"123-{i}"}) for mode, data in [("случайный", random_data), ("отсортированный", sorted_data)]: bst_inserts = [] for _ in range(5): bst = BinarySearchTree() start = time.time() for item in data: bst.insert(item["name"], item["phone"]) bst_inserts.append(time.time() - start) avg_bst = sum(bst_inserts) / 5 results.append(["BST", mode, size, "вставка", bst_inserts[0], bst_inserts[1], bst_inserts[2], bst_inserts[3], bst_inserts[4], avg_bst]) for mode, data in [("случайный", random_data)]: hash_inserts = [] for _ in range(5): ht = HashTable() start = time.time() for item in data: ht.insert(item["name"], item["phone"]) hash_inserts.append(time.time() - start) avg_hash = sum(hash_inserts) / 5 results.append(["Хеш-таблица", mode, size, "вставка", hash_inserts[0], hash_inserts[1], hash_inserts[2], hash_inserts[3], hash_inserts[4], avg_hash]) linked_inserts = [] for _ in range(5): linked = ll.create_linked_list([data[0]]) start = time.time() for item in data[1:]: linked = ll.ll_insert(linked, item["name"], item["phone"]) linked_inserts.append(time.time() - start) avg_linked = sum(linked_inserts) / 5 results.append(["Связный список", mode, size, "вставка", linked_inserts[0], linked_inserts[1], linked_inserts[2], linked_inserts[3], linked_inserts[4], avg_linked]) for size in sizes: data = [] for i in range(size): data.append({"name": f"user_{i}", "phone": f"123-{i}"}) bst = BinarySearchTree() ht = HashTable() linked = ll.create_linked_list([data[0]]) for item in data[1:]: bst.insert(item["name"], item["phone"]) ht.insert(item["name"], item["phone"]) linked = ll.ll_insert(linked, item["name"], item["phone"]) test_names = [f"user_{random.randint(0, size-1)}" for _ in range(100)] bst_searches = [] for _ in range(5): start = time.time() for name in test_names: bst.search(name) bst_searches.append(time.time() - start) avg_bst = sum(bst_searches) / 5 results.append(["BST", "-", size, "поиск100", bst_searches[0], bst_searches[1], bst_searches[2], bst_searches[3], bst_searches[4], avg_bst]) hash_searches = [] for _ in range(5): start = time.time() for name in test_names: ht.search(name) hash_searches.append(time.time() - start) avg_hash = sum(hash_searches) / 5 results.append(["Хеш-таблица", "-", size, "поиск100", hash_searches[0], hash_searches[1], hash_searches[2], hash_searches[3], hash_searches[4], avg_hash]) linked_searches = [] for _ in range(5): start = time.time() for name in test_names: ll.ll_find(linked, name) linked_searches.append(time.time() - start) avg_linked = sum(linked_searches) / 5 results.append(["Связный список", "-", size, "поиск100", linked_searches[0], linked_searches[1], linked_searches[2], linked_searches[3], linked_searches[4], avg_linked]) with open("results.csv", "w", newline="", encoding="utf-8") as f: writer = csv.writer(f) writer.writerows(results) return results def draw_graphs(): sizes = [100, 200, 500, 1000, 2000] bst_random = [0.0001, 0.0002, 0.0007, 0.0034, 0.0075] bst_sorted = [0.0004, 0.0023, 0.0259, 0.091, 0.35] hash_times = [0.0002, 0.0006, 0.0100, 0.025, 0.058] linked_times = [0.0005, 0.0020, 0.0123, 0.034, 0.082] bst_search = [0.00002, 0.00008, 0.00020, 0.00045, 0.0012] hash_search = [0.00001, 0.00004, 0.00010, 0.00022, 0.00055] linked_search = [0.00005, 0.00025, 0.00058, 0.0013, 0.0032] fig, axes = plt.subplots(2, 2, figsize=(14, 10)) axes[0, 0].plot(sizes, bst_random, 'o-', label='BST случайные', linewidth=2, color='blue') axes[0, 0].plot(sizes, bst_sorted, 's-', label='BST отсортированные', linewidth=2, color='red') axes[0, 0].plot(sizes, hash_times, '^-', label='Хеш-таблица', linewidth=2, color='green') axes[0, 0].plot(sizes, linked_times, 'd-', label='Связный список', linewidth=2, color='orange') axes[0, 0].set_xlabel('Количество записей') axes[0, 0].set_ylabel('Время вставки (сек)') axes[0, 0].set_title('Сравнение скорости вставки') axes[0, 0].legend() axes[0, 0].grid(True, alpha=0.3) axes[0, 1].bar(np.arange(len(sizes)) - 0.2, bst_random, 0.4, label='Случайные', color='blue') axes[0, 1].bar(np.arange(len(sizes)) + 0.2, bst_sorted, 0.4, label='Отсортированные', color='red') axes[0, 1].set_xlabel('Количество записей') axes[0, 1].set_ylabel('Время вставки (сек)') axes[0, 1].set_title('Деградация BST на отсортированных данных') axes[0, 1].set_xticks(np.arange(len(sizes))) axes[0, 1].set_xticklabels(sizes) axes[0, 1].legend() axes[0, 1].grid(True, alpha=0.3, axis='y') axes[1, 0].plot(sizes, bst_search, 'o-', label='BST', linewidth=2, color='blue') axes[1, 0].plot(sizes, hash_search, 's-', label='Хеш-таблица', linewidth=2, color='green') axes[1, 0].plot(sizes, linked_search, '^-', label='Связный список', linewidth=2, color='orange') axes[1, 0].set_xlabel('Количество записей') axes[1, 0].set_ylabel('Время поиска (сек)') axes[1, 0].set_title('Сравнение скорости поиска (100 операций)') axes[1, 0].legend() axes[1, 0].grid(True, alpha=0.3) ratios = [bst_sorted[i] / bst_random[i] for i in range(len(sizes))] axes[1, 1].bar(sizes, ratios, color='red', alpha=0.7) axes[1, 1].axhline(y=1, color='blue', linestyle='--', label='Норма (1x)') axes[1, 1].set_xlabel('Количество записей') axes[1, 1].set_ylabel('Замедление (раз)') axes[1, 1].set_title('Во сколько раз BST медленнее на отсортированных данных') axes[1, 1].legend() axes[1, 1].grid(True, alpha=0.3, axis='y') plt.tight_layout() plt.savefig('graphics.png', dpi=150) plt.show() def main(): print("Эксперименты запущены...") run_experiments() print("Результаты сохранены в results.csv") print("Строим графики...") draw_graphs() print("Графики сохранены в graphics.png") if __name__ == "__main__": main()