diff --git a/shalovsa/lab1/docs/report (1).md b/shalovsa/lab1/docs/report (1).md new file mode 100644 index 0000000..10429a4 --- /dev/null +++ b/shalovsa/lab1/docs/report (1).md @@ -0,0 +1,130 @@ +# Отчёт: Задание 1 — Структуры данных + +## Цель работы + +Разработать три структуры данных «с нуля» в процедурном стиле (без ООП), применить их для хранения записей телефонной книги и провести экспериментальное сравнение производительности ключевых операций. + +**Структуры данных:** +- Связный список (LinkedList) +- Хеш-таблица (HashTable) +- Двоичное дерево поиска (BST) + +--- + +## Реализация + +### Основные технические решения + +#### 1. Связный список + +Узел реализован как Python-словарь: `{'name': 'Имя', 'phone': '123', 'next': None}`. + +Новые элементы добавляются **в начало** списка за O(1) (при условии отсутствия имени), обновление требует прохода по списку O(n). Поиск и удаление работают за линейное время из-за отсутствия прямого доступа по индексу. + +#### 2. Хеш-таблица + +Фиксированный массив на 256 корзин. Каждая корзина — указатель на связный список (метод цепочек). Хеш-функция: стандартный `hash(name) % size`. Среднее время операций O(1), при коллизиях — O(k), где k — длина цепочки. + +#### 3. Двоичное дерево поиска (BST) + +Узел: `{'name': 'Имя', 'phone': '123', 'left': None, 'right': None}`. Сравнение ключей — лексикографическое по полю name. Вставка и поиск реализованы итеративно. Удаление — рекурсивное с заменой на минимальный узел правого поддерева. Обход в глубину даёт отсортированный список. + +--- + +## Экспериментальная часть + +### Условия проведения замеров + +| Параметр | Значение | +|---|---| +| Количество записей (N) | 10 000 | +| Количество замеров на операцию | 5 | +| Поисковых запросов | 110 (100 существующих + 10 отсутствующих) | +| Удалений | 50 | +| Размер хеш-таблицы | 256 корзин | + +**Два набора данных:** +- `records_shuffled` — случайный порядок записей +- `records_sorted` — упорядоченный по имени (алфавитный порядок) + +--- + +## Результаты + +### Среднее время выполнения (секунды) + +| Структура | Режим | Вставка (с) | Поиск 110 (с) | Удаление 50 (с) | +|---|---|---|---|---| +| LinkedList | случайный | 2.541985 | 0.034289 | 0.020349 | +| LinkedList | сортированный | 2.208557 | 0.025340 | 0.016424 | +| HashTable | случайный | 0.018235 | 0.000214 | 0.000120 | +| HashTable | сортированный | 0.016163 | 0.000207 | 0.000124 | +| BST | случайный | 0.017192 | 0.000145 | 0.000104 | +| **BST** | **сортированный** | **3.854338** | **0.033498** | **0.045823** | + +### Визуализация + +![Сравнение по операциям](data/comparison_by_operation.png) + +![Влияние порядка данных](data/sorted_vs_random.png) + +--- + +## Анализ результатов + +### 1. Связный список — стабильно низкая скорость + +Вставка требует **~2.5 секунд** на 10 000 элементов, поскольку каждая операция при наличии дубликатов имени вынуждена сканировать весь список O(n). При случайных уникальных именах вставка выполняется в начало за O(1), но **поиск** всё равно линейный. + +**Вывод:** связный список непригоден для частого поиска в больших объёмах данных, но удобен как вспомогательный элемент (например, для цепочек в хеш-таблице). + +### 2. Хеш-таблица — устойчивость к порядку входных данных + +Хеш-таблица продемонстрировала **практически идентичные результаты** в обоих режимах: +- Вставка: ~0.017 с (быстрее списка в ~150 раз) +- Поиск: ~0.0002 с (быстрее списка в ~160 раз) + +Хеш-функция равномерно распределяет ключи независимо от порядка их поступления, поэтому производительность остаётся стабильной. + +### 3. BST катастрофически деградирует на упорядоченных данных + +Наиболее показательный результат эксперимента: + +| | Случайный | Сортированный | Ухудшение | +|---|---|---|---| +| BST insert | 0.017 с | **3.854 с** | **×225** | +| BST find | 0.000145 с | **0.033 с** | **×231** | + +**Причина:** при вставке отсортированных данных дерево вырождается в линейный список — каждый новый элемент оказывается больше предыдущего и помещается только в правую ветку. Высота дерева становится O(n) вместо O(log n), что превращает все операции в линейные. + +### 4. Операция delete + +На случайных данных BST удаляет за **~0.0001 с** (логарифмическая сложность). На сортированных — **~0.046 с** (линейная деградация). HashTable показывает стабильные **~0.00012 с** независимо от порядка. + +--- + +## Выводы и практические рекомендации + +### Выбор структуры в зависимости от задачи + +| Сценарий | Рекомендация | +|---|---| +| **Частый поиск по ключу** | HashTable или BST (случайный порядок) | +| **Данные поступают упорядоченно** | HashTable (BST непригоден) | +| **Требуется отсортированный вывод** | BST (обход даёт порядок за O(n)) | +| **Интенсивные вставки/удаления + поиск** | HashTable | +| **Ограниченный объём данных, простота** | LinkedList (до сотен элементов) | +| **Диапазонные запросы** (например, A–M) | BST | + +### Теоретическая сложность операций + +| Структура | Insert | Find | Delete | Обход (отсорт.) | +|---|---|---|---|---| +| LinkedList | O(n) | O(n) | O(n) | O(n log n) | +| HashTable | O(1) в среднем | O(1) в среднем | O(1) в среднем | O(n log n) | +| BST (сбалансированный) | O(log n) | O(log n) | O(log n) | O(n) | +| BST (вырожденный) | O(n) | O(n) | O(n) | O(n) | + +### Ключевой вывод + +Для телефонного справочника с частыми поисками и обновлениями оптимальный выбор — **хеш-таблица**. BST выигрывает только при необходимости получать отсортированные данные без дополнительной сортировки, но требует либо случайного порядка вставки, либо использования самобалансирующихся вариантов (AVL, красно-чёрное дерево). diff --git a/shalovsa/lab1/docs/report_full.ipynb b/shalovsa/lab1/docs/report_full.ipynb deleted file mode 100644 index 8672000..0000000 --- a/shalovsa/lab1/docs/report_full.ipynb +++ /dev/null @@ -1,41 +0,0 @@ -{ - "metadata": { - "kernelspec": { - "display_name": "Python (Pyodide)", - "language": "python", - "name": "python" - }, - "language_info": { - "codemirror_mode": { - "name": "python", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8" - } - }, - "nbformat_minor": 5, - "nbformat": 4, - "cells": [ - { - "id": "eb4edc6f-c633-467e-abbb-e7ed9d5dd8fa", - "cell_type": "markdown", - "source": "# Отчёт: Задание 1 — Структуры данных\n\n## Цель работы\n\nРазработать три структуры данных «с нуля» в процедурном стиле (без ООП), применить их для хранения записей телефонной книги и провести экспериментальное сравнение производительности ключевых операций.\n\n**Структуры данных:**\n- Связный список (LinkedList)\n- Хеш-таблица (HashTable)\n- Двоичное дерево поиска (BST)\n\n---\n\n## Реализация\n\n### Основные технические решения\n\n#### 1. Связный список\n\nУзел реализован как Python-словарь: `{'name': 'Имя', 'phone': '123', 'next': None}`.\n\nНовые элементы добавляются **в начало** списка за O(1) (при условии отсутствия имени), обновление требует прохода по списку O(n). Поиск и удаление работают за линейное время из-за отсутствия прямого доступа по индексу.\n\n#### 2. Хеш-таблица\n\nФиксированный массив на 256 корзин. Каждая корзина — указатель на связный список (метод цепочек). Хеш-функция: стандартный `hash(name) % size`. Среднее время операций O(1), при коллизиях — O(k), где k — длина цепочки.\n\n#### 3. Двоичное дерево поиска (BST)\n\nУзел: `{'name': 'Имя', 'phone': '123', 'left': None, 'right': None}`. Сравнение ключей — лексикографическое по полю name. Вставка и поиск реализованы итеративно. Удаление — рекурсивное с заменой на минимальный узел правого поддерева. Обход в глубину даёт отсортированный список.\n\n---\n\n## Экспериментальная часть\n\n### Условия проведения замеров\n\n| Параметр | Значение |\n|---|---|\n| Количество записей (N) | 10 000 |\n| Количество замеров на операцию | 5 |\n| Поисковых запросов | 110 (100 существующих + 10 отсутствующих) |\n| Удалений | 50 |\n| Размер хеш-таблицы | 256 корзин |\n\n**Два набора данных:**\n- `records_shuffled` — случайный порядок записей\n- `records_sorted` — упорядоченный по имени (алфавитный порядок)\n\n---\n\n## Результаты\n\n### Среднее время выполнения (секунды)\n\n| Структура | Режим | Вставка (с) | Поиск 110 (с) | Удаление 50 (с) |\n|---|---|---|---|---|\n| LinkedList | случайный | 2.541985 | 0.034289 | 0.020349 |\n| LinkedList | сортированный | 2.208557 | 0.025340 | 0.016424 |\n| HashTable | случайный | 0.018235 | 0.000214 | 0.000120 |\n| HashTable | сортированный | 0.016163 | 0.000207 | 0.000124 |\n| BST | случайный | 0.017192 | 0.000145 | 0.000104 |\n| **BST** | **сортированный** | **3.854338** | **0.033498** | **0.045823** |\n\n### Визуализация\n\n![Сравнение по операциям](data/comparison_by_operation.png)\n\n![Влияние порядка данных](data/sorted_vs_random.png)\n\n---\n\n## Анализ результатов\n\n### 1. Связный список — стабильно низкая скорость\n\nВставка требует **~2.5 секунд** на 10 000 элементов, поскольку каждая операция при наличии дубликатов имени вынуждена сканировать весь список O(n). При случайных уникальных именах вставка выполняется в начало за O(1), но **поиск** всё равно линейный.\n\n**Вывод:** связный список непригоден для частого поиска в больших объёмах данных, но удобен как вспомогательный элемент (например, для цепочек в хеш-таблице).\n\n### 2. Хеш-таблица — устойчивость к порядку входных данных\n\nХеш-таблица продемонстрировала **практически идентичные результаты** в обоих режимах:\n- Вставка: ~0.017 с (быстрее списка в ~150 раз)\n- Поиск: ~0.0002 с (быстрее списка в ~160 раз)\n\nХеш-функция равномерно распределяет ключи независимо от порядка их поступления, поэтому производительность остаётся стабильной.\n\n### 3. BST катастрофически деградирует на упорядоченных данных\n\nНаиболее показательный результат эксперимента:\n\n| | Случайный | Сортированный | Ухудшение |\n|---|---|---|---|\n| BST insert | 0.017 с | **3.854 с** | **×225** |\n| BST find | 0.000145 с | **0.033 с** | **×231** |\n\n**Причина:** при вставке отсортированных данных дерево вырождается в линейный список — каждый новый элемент оказывается больше предыдущего и помещается только в правую ветку. Высота дерева становится O(n) вместо O(log n), что превращает все операции в линейные.\n\n### 4. Операция delete\n\nНа случайных данных BST удаляет за **~0.0001 с** (логарифмическая сложность). На сортированных — **~0.046 с** (линейная деградация). HashTable показывает стабильные **~0.00012 с** независимо от порядка.\n\n---\n\n## Выводы и практические рекомендации\n\n### Выбор структуры в зависимости от задачи\n\n| Сценарий | Рекомендация |\n|---|---|\n| **Частый поиск по ключу** | HashTable или BST (случайный порядок) |\n| **Данные поступают упорядоченно** | HashTable (BST непригоден) |\n| **Требуется отсортированный вывод** | BST (обход даёт порядок за O(n)) |\n| **Интенсивные вставки/удаления + поиск** | HashTable |\n| **Ограниченный объём данных, простота** | LinkedList (до сотен элементов) |\n| **Диапазонные запросы** (например, A–M) | BST |\n\n### Теоретическая сложность операций\n\n| Структура | Insert | Find | Delete | Обход (отсорт.) |\n|---|---|---|---|---|\n| LinkedList | O(n) | O(n) | O(n) | O(n log n) |\n| HashTable | O(1) в среднем | O(1) в среднем | O(1) в среднем | O(n log n) |\n| BST (сбалансированный) | O(log n) | O(log n) | O(log n) | O(n) |\n| BST (вырожденный) | O(n) | O(n) | O(n) | O(n) |\n\n### Ключевой вывод\n\nДля телефонного справочника с частыми поисками и обновлениями оптимальный выбор — **хеш-таблица**. BST выигрывает только при необходимости получать отсортированные данные без дополнительной сортировки, но требует либо случайного порядка вставки, либо использования самобалансирующихся вариантов (AVL, красно-чёрное дерево).", - "metadata": {} - }, - { - "id": "00c3b29d-3742-471c-b8e1-f432ee2d10c4", - "cell_type": "code", - "source": "", - "metadata": { - "trusted": true - }, - "outputs": [], - "execution_count": null - } - ] -} \ No newline at end of file