2026-rff_mp/meosyam/docs/1-report.md
2026-09-03 13:03:53 +00:00

72 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Отчёт по лабораторной работе «Структуры данных»
## 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`.*
Графическое сравнение представлено на рисунке ниже.
![Сравнение производительности](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, красно-чёрные деревья), которые гарантируют логарифмическую высоту.
- **Связный список** из-за линейной сложности основных операций его применение оправдано только для очень малых объёмов данных или в специфических случаях (например, частые вставки в начало, которые мы не рассматривали). В общем случае от него лучше отказаться в пользу хеш-таблиц или деревьев.
Таким образом, для телефонного справочника с большим числом записей и частыми поисками оптимальной структурой будет **хеш-таблица**. Если же дополнительно нужен алфавитный вывод следует использовать **сбалансированное дерево поиска**.