2026-rff_mp/meosyam/docs/1-report.md

72 lines
8.6 KiB
Markdown
Raw Normal View History

# Отчёт по лабораторной работе «Структуры данных»
## 1. Цель работы
Реализовать три структуры данных (связный список, хеш-таблицу, двоичное дерево поиска) для хранения телефонного справочника и экспериментально сравнить их производительность на операциях вставки, поиска и удаления. Оценить влияние порядка входных данных на эффективность каждой структуры.
## 2. Реализация
Все структуры реализованы в процедурном стиле (без классов) с использованием словарей для узлов.
- **Связный список** операции выполняются за линейное время, поиск и удаление требуют прохода по элементам.
- **Хеш-таблица** размер корзин = 10, хеш-функция на основе суммы кодов символов. В каждой корзине хранится связный список для разрешения коллизий.
- **Двоичное дерево поиска** обычное (несбалансированное) дерево, операции вставки/поиска/удаления рекурсивные.
## 3. Методика эксперимента
- **Объём данных**: N = 1000 записей вида `User_00001``User_01000` с случайными номерами телефонов.
- **Два режима**:
- `случайный` записи подаются в случайном порядке;
- `отсортированный` записи подаются по алфавиту имён.
- **Замеряемые операции**:
- Вставка всех N записей (общее время).
- Поиск 100 существующих и 10 несуществующих имён (общее время).
- Удаление 50 случайных существующих записей (общее время).
- **Повторы**: каждый эксперимент проведён 5 раз, в таблицах приведены средние значения.
- **Измерения**: использован `time.perf_counter()`.
## 4. Результаты измерений
Усреднённые времена (в секундах) для каждой структуры и режима:
| Структура | Режим | Вставка (с) | Поиск (с) | Удаление (с) |
|-------------|-------------|-------------|-----------|--------------|
| LinkedList | случайный | 0.1134 | 0.0076 | 0.0031 |
| LinkedList | сортир. | 0.1121 | 0.0069 | 0.0030 |
| HashTable | случайный | 0.0142 | 0.0011 | 0.0006 |
| HashTable | сортир. | 0.0150 | 0.0012 | 0.0006 |
| BST | случайный | 0.0051 | 0.00035 | 0.00015 |
| BST | сортир. | 0.295 | 0.022 | 0.011 |
*Полные данные всех 5 повторений сохранены в `experiment_results.csv`.*
Графическое сравнение представлено на рисунке ниже.
2026-09-03 13:03:53 +00:00
![Сравнение производительности](data/1/performance_comparison.png)
## 5. Анализ результатов
### 5.1. Влияние порядка на BST
При подаче имён в отсортированном порядке дерево вырождается в правую «цепочку» (высота = N). Это приводит к деградации всех операций до **O(N)**. Эксперимент подтверждает:
- время вставки на отсортированных данных в **~58 раз** больше, чем на случайных;
- поиск замедляется в **~63 раза**;
- удаление в **~73 раза**.
Такой эффект объясняется отсутствием балансировки дерево становится аналогичным связному списку, но с дополнительными накладными расходами на рекурсию.
### 5.2. Устойчивость хеш-таблицы к порядку
Хеш-таблица распределяет ключи по корзинам на основе хеш-значения, которое не зависит от порядка поступления. Поэтому разница между случайным и сортированным режимами незначительна (колебания в пределах погрешности). Средняя сложность операций остаётся близкой к **O(1)**.
### 5.3. Медлительность связного списка
Список всегда требует последовательного обхода для поиска и удаления (сложность **O(N)**). Даже при случайном порядке поиск занимает на порядок больше времени, чем в хеш-таблице или BST. Вставка в конец также требует прохода до конца, что делает её медленнее, чем у хеш-таблицы.
### 5.4. Особенности удаления
- **Связный список** удаление требует сначала найти элемент (O(N)), затем переставить ссылки (O(1)). Время удаления примерно соответствует времени поиска.
- **Хеш-таблица** удаление почти мгновенное (O(1) в среднем), так как поиск элемента в корзине происходит внутри короткого списка.
- **BST** на случайных данных удаление очень быстрое (O(log N)), но на отсортированных замедляется до O(N) из-за вырождения дерева.
## 6. Выводы и рекомендации
На основе полученных данных можно сделать следующие выводы:
- **Хеш-таблица** лучший выбор для задач, где критична скорость поиска, вставки и удаления, а порядок хранения не важен. Она устойчива к любым порядкам данных и даёт предсказуемую производительность. Рекомендуется для реализации словарей, кэшей, индексов.
- **Двоичное дерево поиска** полезно, когда требуется часто получать данные в отсортированном порядке (например, вывод всех записей по алфавиту). Однако при работе с отсортированными входными данными его производительность резко падает. В реальных проектах следует использовать сбалансированные варианты (AVL, красно-чёрные деревья), которые гарантируют логарифмическую высоту.
- **Связный список** из-за линейной сложности основных операций его применение оправдано только для очень малых объёмов данных или в специфических случаях (например, частые вставки в начало, которые мы не рассматривали). В общем случае от него лучше отказаться в пользу хеш-таблиц или деревьев.
Таким образом, для телефонного справочника с большим числом записей и частыми поисками оптимальной структурой будет **хеш-таблица**. Если же дополнительно нужен алфавитный вывод следует использовать **сбалансированное дерево поиска**.