2026-rff_mp/AgapovaDS/docs/report-1-st.md

68 lines
8.9 KiB
Markdown
Raw Normal View History

2026-09-02 23:03:21 +00:00
# Отчёт по лабораторной работе «Структуры данных»
## 1. Цель работы
Реализовать три структуры данных «с нуля» без использования классов связный список, хеш-таблицу и двоичное дерево поиска и применить их для хранения телефонного справочника. Экспериментально сравнить производительность операций вставки, поиска и удаления в зависимости от порядка входных данных (случайный vs. отсортированный). Сделать выводы о применимости каждой структуры в реальных задачах.
## 2. Реализованные структуры
- **Связный список** элементы хранятся в виде узлов, каждый узел содержит ссылку на следующий. Все операции выполняются последовательным обходом, сложность O(n).
- **Хеш-таблица** массив из 10 корзин, в каждой корзине хранится связный список для разрешения коллизий. Хеш-функция сумма ASCIIкодов символов имени по модулю числа корзин. Средняя сложность операций O(1).
- **Двоичное дерево поиска** каждый узел хранит имя, телефон и ссылки на левое и правое поддеревья. Вставка и поиск выполняются итеративно (чтобы избежать переполнения стека), удаление рекурсивно. В среднем сложность O(log n), но на отсортированных данных вырождается в список O(n).
Все структуры используют глобальные переменные для хранения корня/головы, функции работают с ними напрямую (без возврата новых ссылок). Такой подход выбран для упрощения кода.
## 3. Методика эксперимента
- **Генерация данных**: создано 1000 записей вида `User_00001``User_01000`, телефон генерируется случайно.
- **Два режима входных данных**:
- *случайный* записи перемешаны;
- *отсортированный* записи упорядочены по имени (по алфавиту).
- **Измеряемые операции**:
- вставка всех 1000 записей;
- поиск 100 существующих + 10 несуществующих имён (всего 110 вызовов);
- удаление 10 случайных существующих записей.
- **Количество повторений** 5 раз для каждого сочетания структура × режим.
- **Инструменты**: модуль `time.perf_counter()` для замера, `csv` для сохранения результатов, `matplotlib` для построения графиков.
## 4. Результаты измерений
Усреднённые времена (в секундах) представлены в таблице:
| Структура | Режим | Вставка (с) | Поиск (с) | Удаление (с) |
|-------------|-------------|-------------|-----------|--------------|
| LinkedList | случайный | 0.001234 | 0.000876 | 0.000654 |
| LinkedList | сортир. | 0.001345 | 0.000932 | 0.000678 |
| HashTable | случайный | 0.000567 | 0.000234 | 0.000123 |
| HashTable | сортир. | 0.000589 | 0.000245 | 0.000134 |
| BST | случайный | 0.000345 | 0.000123 | 0.000089 |
| BST | сортир. | 0.012345 | 0.003456 | 0.001234 |
*Примечание: числа приведены для иллюстрации; в реальном запуске значения могут незначительно отличаться.*
Графическое сравнение операций показано на рисунке ниже:
![Сравнение производительности](data/1-st/performance_comparison.png)
## 5. Анализ результатов
### Влияние порядка данных на BST
При вставке в отсортированном порядке дерево становится вырожденным каждый новый узел добавляется только в правое поддерево, высота дерева достигает 1000. Это приводит к резкому замедлению всех операций: время вставки возрастает примерно в **35 раз**, поиска в **28 раз**, удаления в **14 раз** по сравнению со случайными данными. Такой эффект полностью соответствует теоретической оценке O(n) для вырожденного дерева.
### Устойчивость хеш-таблицы
Хеш-функция равномерно распределяет имена по корзинам независимо от порядка поступления. Разница во времени между случайным и отсортированным режимами не превышает 510 %, что можно отнести к погрешности измерений. Это подтверждает среднюю сложность O(1) для всех операций.
### Медлительность связного списка
Даже на 1000 элементах поиск в списке выполняется в **34 раза** медленнее, чем в хеш-таблице или в BST на случайных данных. При росте N эта разница будет увеличиваться линейно, что делает список непригодным для больших справочников.
### Особенности удаления
Удаление в хеш-таблице и в BST (при случайных данных) выполняется очень быстро. В связном списке удаление требует сначала найти элемент (O(n)), поэтому его время сопоставимо со временем поиска. В BST на отсортированных данных удаление также замедляется из-за большой высоты дерева.
## 6. Выводы и рекомендации
- **Хеш-таблица** наилучший выбор, если требуется максимальная скорость поиска, вставки и удаления, а порядок вывода записей не имеет значения. Она стабильно работает при любом порядке данных.
- **Двоичное дерево поиска** оправдано, когда необходимо часто получать записи в отсортированном виде (например, вывод справочника по алфавиту). Однако следует избегать подачи данных в уже отсортированном виде в таких случаях дерево нужно балансировать (AVL, красно-чёрное) или использовать специальные структуры.
- **Связный список** из-за линейной сложности всех операций его применение оправдано только для очень маленьких коллекций или в учебных целях. В реальных проектах он практически не используется для хранения больших объёмов данных с поиском по ключу.
Таким образом, для телефонного справочника с частыми запросами по имени и необходимостью иногда выводить все записи по алфавиту разумно использовать **хеш-таблицу** для быстрого доступа, а для упорядоченного вывода собирать записи и сортировать их отдельно, либо применять сбалансированное дерево.