[1] исправил отчёт

This commit is contained in:
shalovsa 2026-05-11 17:25:51 +03:00
parent b8b0e6d50f
commit 9ada5f7c9f
2 changed files with 130 additions and 41 deletions

View File

@ -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 (до сотен элементов) |
| **Диапазонные запросы** (например, AM) | 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, красно-чёрное дерево).

File diff suppressed because one or more lines are too long