From 061eb851af2a96e2f2047d0cfe51e4e53fe8a6ec Mon Sep 17 00:00:00 2001 From: Veronika Minina Date: Sat, 16 May 2026 17:28:21 +0300 Subject: [PATCH] [0] initial commit --- MininaVD/docs/data/Laba1dop.txt | 311 +++++++++++++++++++++++++++++--- 1 file changed, 281 insertions(+), 30 deletions(-) diff --git a/MininaVD/docs/data/Laba1dop.txt b/MininaVD/docs/data/Laba1dop.txt index 6fe1a5a..80239a6 100644 --- a/MininaVD/docs/data/Laba1dop.txt +++ b/MininaVD/docs/data/Laba1dop.txt @@ -1,3 +1,12 @@ +import time +import random +import csv +import os +import matplotlib.pyplot as plt +import numpy as np +import sys +sys.setrecursionlimit(20000) + Linked List Phone Book: def ll_insert(head, name, phone): @@ -46,35 +55,6 @@ def ll_print_all(head): records = ll_list_all(head) for record in records: print(f"{record['name']}: {record['phone']}") -head = None -#добавление записей -print("\n1. Добавляем записи в список:") -head = ll_insert(head, "Анна", "123") -head = ll_insert(head, "Сергей", "234") -head = ll_insert(head, "Георгий", "345") -head = ll_insert(head, "Виктория", "456") -ll_print_all(head) -#Обновляем номер -print("\n2. Добавляем новую запись:") -head = ll_insert(head, "Антон", "666") -ll_print_all(head) - -# Поиск записей -print(f"\n3. Производим поиск записей: \nПоиск Алисы: {ll_find(head, 'Анна')}") -print(f"Поиск Елены: {ll_find(head, 'Елена')}") - -# Удаление записей -print("\n4. Удаляем Владимира:") -head = ll_delete(head, "Владимир") -ll_print_all(head) - -print("\n5. Удаляем Антона:") -head = ll_delete(head, "Антон") -ll_print_all(head) - -print("\n6. Пробуем удалить несуществующую запись:") -head = ll_delete(head, "Некто") -ll_print_all(head) Hash Function: @@ -203,4 +183,275 @@ def generate_records(count=10000): random.shuffle(shuffled) sorted_records = sorted(records, key=lambda x: x[0]) - return shuffled, sorted_records \ No newline at end of file + return shuffled, sorted_records + +2. Timing + +def measure_insertion(structure_name, records): + + times = [] + filled_structure = None + + for run in range(5): + if structure_name == "linked_list": + structure = None + elif structure_name == "hash_table": + structure = ht_create(1000) + elif structure_name == "bst": + structure = None + + start = time.perf_counter() + + for name, phone in records: + if structure_name == "linked_list": + structure = ll_insert(structure, name, phone) + elif structure_name == "hash_table": + ht_insert(structure, name, phone) + elif structure_name == "bst": + structure = bst_insert(structure, name, phone) + + end = time.perf_counter() + times.append(end - start) + + if run == 4: + filled_structure = structure + + return times, filled_structure + + +def measure_search(structure_name, structure, search_names): + + times = [] + + for run in range(5): + start = time.perf_counter() + + for name in search_names: + if structure_name == "linked_list": + ll_find(structure, name) + elif structure_name == "hash_table": + ht_find(structure, name) + elif structure_name == "bst": + bst_find(structure, name) + + end = time.perf_counter() + times.append(end - start) + + return times + + +def measure_deletion(structure_name, original_structure, delete_names): + + times = [] + + for run in range(5): + if structure_name == "linked_list": + all_records = ll_list_all(original_structure) + test_structure = None + for name, phone in all_records: + test_structure = ll_insert(test_structure, name, phone) + + elif structure_name == "hash_table": + all_records = ht_list_all(original_structure) + test_structure = ht_create(1000) + for name, phone in all_records: + ht_insert(test_structure, name, phone) + + elif structure_name == "bst": + all_records = bst_list_all(original_structure) + test_structure = None + for name, phone in all_records: + test_structure = bst_insert(test_structure, name, phone) + + start = time.perf_counter() + + for name in delete_names: + if structure_name == "linked_list": + test_structure = ll_delete(test_structure, name) + elif structure_name == "hash_table": + ht_delete(test_structure, name) + elif structure_name == "bst": + test_structure = bst_delete(test_structure, name) + + end = time.perf_counter() + times.append(end - start) + + return times +3. Launch and save results + +def run_experiment(): + + current_dir = os.path.dirname(__file__) + docs_dir = os.path.dirname(current_dir) + csv_file = os.path.join(docs_dir, "experiment_results.csv") + + print("ЭКСПЕРИМЕНТАЛЬНОЕ СРАВНЕНИЕ СТРУКТУР ДАННЫХ") + print("Телефонный справочник - 10000 записей") + print(f"\n Результаты будут сохранены в: {csv_file}") + + shuffled_records, sorted_records = generate_records(10000) + print(f" Сгенерировано 10000 записей") + + existing_names = [shuffled_records[i][0] for i in random.sample(range(10000), 100)] + nonexisting_names = [f"NotExist_{i}" for i in range(10)] + search_names = existing_names + nonexisting_names + delete_names = [shuffled_records[i][0] for i in random.sample(range(10000), 50)] + + results = [["Структура", "Режим", "Операция", + "Замер1(с)", "Замер2(с)", "Замер3(с)", "Замер4(с)", "Замер5(с)", + "Среднее(с)"]] + + for mode_name, records in [("случайный", shuffled_records), + ("отсортированный", sorted_records)]: + + print(f"\n2. Тестирование режима: {mode_name}") + + for struct_name in ["linked_list", "hash_table", "bst"]: + print(f"\n {struct_name.upper()}:") + + print(" Вставка 10000 записей") + insert_times, filled_struct = measure_insertion(struct_name, records) + avg_insert = sum(insert_times) / 5 + print(f" Время: {avg_insert:.4f} сек (среднее)") + + print(" Поиск 110 записей") + search_times = measure_search(struct_name, filled_struct, search_names) + avg_search = sum(search_times) / 5 + print(f" Время: {avg_search:.4f} сек (среднее)") + + print(" Удаление 50 записей") + delete_times = measure_deletion(struct_name, filled_struct, delete_names) + avg_delete = sum(delete_times) / 5 + print(f" Время: {avg_delete:.4f} сек (среднее)") + + results.append([struct_name, mode_name, "вставка"] + insert_times + [avg_insert]) + results.append([struct_name, mode_name, "поиск"] + search_times + [avg_search]) + results.append([struct_name, mode_name, "удаление"] + delete_times + [avg_delete]) + + print("\n3. Сохранение результатов") + with open(csv_file, "w", newline="", encoding="utf-8") as f: + writer = csv.writer(f) + writer.writerows(results) + print(f" Результаты сохранены в: {csv_file}") + + print("СВОДНАЯ ТАБЛИЦА РЕЗУЛЬТАТОВ") + print(f"{'Структура':<15} {'Режим':<12} {'Операция':<10} {'Среднее время (сек)':<20}") + + for row in results[1:]: + struct, mode, op, t1, t2, t3, t4, t5, avg = row + print(f"{struct:<15} {mode:<12} {op:<10} {avg:<20.6f}") + + return results, docs_dir + +4. Graphics + +def create_graphs(results, docs_dir): + + print("\n4. Построение графиков") + + data = {} + for row in results[1:]: + struct = row[0] + mode = row[1] + op = row[2] + avg = row[8] + + if struct not in data: + data[struct] = {} + if mode not in data[struct]: + data[struct][mode] = {} + data[struct][mode][op] = avg + + + struct_labels = { + 'linked_list': 'LinkedList', + 'hash_table': 'HashTable', + 'bst': 'BST' + } + + + colors = { + 'linked_list': '#8b00ff', + 'hash_table': '#81d8d0', + 'bst': '#000000' + } + + + fig, axes = plt.subplots(1, 3, figsize=(15, 6)) + fig.suptitle('Сравнение производительности структур данных', fontsize=16, fontweight='bold') + + operations = ['вставка', 'поиск', 'удаление'] + operation_titles = ['Вставка\n(10000 записей)', 'Поиск\n(110 запросов)', 'Удаление\n(50 записей)'] + modes = ['случайный', 'отсортированный'] + mode_labels = ['Случайный', 'Отсортированный'] + + for idx, (op, op_title) in enumerate(zip(operations, operation_titles)): + ax = axes[idx] + + # Позиции для групп столбцов + x = np.arange(len(modes)) # [0, 1] + width = 0.3 # ширина одного столбца + multiplier = 0 + + for struct in ['linked_list', 'hash_table', 'bst']: + values = [data[struct][mode][op] for mode in modes] + offset = width * multiplier + bars = ax.bar(x + offset, values, width, + label=struct_labels[struct], + color=colors[struct], + edgecolor='black', linewidth=0.5) + + + for bar, val in zip(bars, values): + if val < 0.01: + ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + val*0.05, + f'{val:.5f}', ha='center', va='bottom', fontsize=8, rotation=0) + else: + ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + val*0.02, + f'{val:.4f}', ha='center', va='bottom', fontsize=8, rotation=0) + + multiplier += 1 + + + ax.set_title(op_title, fontsize=12, fontweight='bold') + ax.set_ylabel('Время (секунды)', fontsize=10) + ax.set_xlabel('Режим данных', fontsize=10) + ax.set_xticks(x + width) + ax.set_xticklabels(mode_labels) + ax.legend(loc='upper left', fontsize=8) + ax.grid(True, alpha=0.3, axis='y') + + + all_values = [data[s][m][op] for s in ['linked_list', 'hash_table', 'bst'] for m in modes] + if max(all_values) / min(all_values) > 100: + ax.set_yscale('log') + ax.set_ylabel('Время (секунды) - логарифмическая шкала', fontsize=9) + + plt.tight_layout() + graph_path = os.path.join(docs_dir, "performance_graphs.png") + plt.savefig(graph_path, dpi=150, bbox_inches='tight') + plt.close() + print(f" Графики сохранены в: {graph_path}") + + return graph_path + +5. Main program + +if __name__ == "__main__": + + results, docs_dir = run_experiment() + + + try: + graph_file = create_graphs(results, docs_dir) + + print("ЭКСПЕРИМЕНТ ЗАВЕРШЕН УСПЕШНО!") + print("\n СОЗДАННЫЕ ФАЙЛЫ:") + print(f" Данные: {os.path.join(docs_dir, 'experiment_results.csv')}") + print(f" Графики: {graph_file}") + + except Exception as e: + print(f"\n Ошибка при построении графиков: {e}") + print(" Убедитесь, что установлен matplotlib: pip install matplotlib") + print("ЭКСПЕРИМЕНТ ЗАВЕРШЕН (без графиков)") + print(f"\n CSV файл сохранен: {os.path.join(docs_dir, 'experiment_results.csv')}") \ No newline at end of file