From 01eabf26552ad17c9bb6c197bdb13afd72273f2c Mon Sep 17 00:00:00 2001 From: Maksim Date: Mon, 18 May 2026 20:08:09 +0300 Subject: [PATCH] [2] 1-st exersize --- .../data/1-st-exercize/LinkedListPhoneBook.py | 258 ++++++++++++++++++ 1 file changed, 258 insertions(+) diff --git a/GorkinMM/docs/data/1-st-exercize/LinkedListPhoneBook.py b/GorkinMM/docs/data/1-st-exercize/LinkedListPhoneBook.py index e69de29..e355578 100644 --- a/GorkinMM/docs/data/1-st-exercize/LinkedListPhoneBook.py +++ b/GorkinMM/docs/data/1-st-exercize/LinkedListPhoneBook.py @@ -0,0 +1,258 @@ +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() \ No newline at end of file