forked from UNN/2026-rff_mp
102 lines
5.5 KiB
Markdown
102 lines
5.5 KiB
Markdown
|
|
# Отчёт по заданию 1 — структуры данных
|
|||
|
|
|
|||
|
|
## Цель работы
|
|||
|
|
|
|||
|
|
Реализовать три структуры данных с нуля в процедурном стиле:
|
|||
|
|
|
|||
|
|
- связный список;
|
|||
|
|
- хеш-таблицу;
|
|||
|
|
- двоичное дерево поиска.
|
|||
|
|
|
|||
|
|
Также были выполнены измерения времени для операций `insert`, `find`, `delete` и построены графики по результатам эксперимента.
|
|||
|
|
|
|||
|
|
## Реализованные структуры
|
|||
|
|
|
|||
|
|
### Связный список
|
|||
|
|
|
|||
|
|
Узел хранится как словарь:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
{"name": "Имя", "phone": "123", "next": None}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Хеш-таблица
|
|||
|
|
|
|||
|
|
Хранится как список бакетов фиксированной длины, где каждый бакет — голова связного списка или `None`.
|
|||
|
|
|
|||
|
|
### Двоичное дерево поиска
|
|||
|
|
|
|||
|
|
Узел хранится как словарь:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
{"name": "Имя", "phone": "123", "left": None, "right": None}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Для BST использованы итеративные операции, чтобы корректно работать и на отсортированных данных.
|
|||
|
|
|
|||
|
|
## Методика эксперимента
|
|||
|
|
|
|||
|
|
- Количество записей: `N = 10000`
|
|||
|
|
- Режимы данных:
|
|||
|
|
- случайный порядок;
|
|||
|
|
- отсортированный порядок.
|
|||
|
|
- Каждое измерение повторялось **5 раз**.
|
|||
|
|
- В CSV сохранены:
|
|||
|
|
- все отдельные замеры;
|
|||
|
|
- среднее время для каждой операции, структуры и режима.
|
|||
|
|
|
|||
|
|
Операции:
|
|||
|
|
|
|||
|
|
- вставка всех записей;
|
|||
|
|
- поиск 100 существующих и 10 отсутствующих имён;
|
|||
|
|
- удаление 50 случайных имён.
|
|||
|
|
|
|||
|
|
## Графики
|
|||
|
|
|
|||
|
|

|
|||
|
|
|
|||
|
|

|
|||
|
|
|
|||
|
|

|
|||
|
|
|
|||
|
|
## Средние результаты
|
|||
|
|
|
|||
|
|
| Режим | Операция | LinkedList | HashTable | BST | Лучший результат |
|
|||
|
|
|---|---:|---:|---:|---:|---|
|
|||
|
|
| случайный | insert | 3.949566 | 0.208964 | 0.018028 | BST |
|
|||
|
|
| случайный | find | 0.033693 | 0.001534 | 0.000190 | BST |
|
|||
|
|
| случайный | delete | 0.016076 | 0.000727 | 0.000102 | BST |
|
|||
|
|
| отсортированный | insert | 2.998378 | 0.208710 | 4.163651 | HashTable |
|
|||
|
|
| отсортированный | find | 0.023923 | 0.001819 | 0.037987 | HashTable |
|
|||
|
|
| отсортированный | delete | 0.011258 | 0.000863 | 0.019363 | HashTable |
|
|||
|
|
|
|||
|
|
## Анализ результатов
|
|||
|
|
|
|||
|
|
### Влияние порядка входных данных на BST
|
|||
|
|
|
|||
|
|
На случайных данных BST работает значительно быстрее, чем на отсортированных. Это связано с тем, что при случайной вставке дерево остаётся ближе к сбалансированному состоянию.
|
|||
|
|
|
|||
|
|
На отсортированных данных дерево вырождается в цепочку, поэтому вставка становится медленной, а поиск и удаление тоже деградируют по времени.
|
|||
|
|
|
|||
|
|
### Почему хеш-таблица почти не чувствительна к порядку
|
|||
|
|
|
|||
|
|
Хеш-таблица распределяет элементы по бакетам через хеш-функцию, поэтому сам порядок входа почти не влияет на скорость. Влияние может появляться только из-за коллизий, но в целом поведение остаётся близким к постоянному времени.
|
|||
|
|
|
|||
|
|
### Почему связный список всегда медленен при поиске
|
|||
|
|
|
|||
|
|
Поиск в связном списке выполняется последовательным просмотром элементов. Поэтому при большом количестве записей приходится проходить много узлов, и операция остаётся линейной по времени.
|
|||
|
|
|
|||
|
|
### Как удаление работает в каждой структуре
|
|||
|
|
|
|||
|
|
- В связном списке нужно сначала найти нужный узел, затем переназначить ссылку.
|
|||
|
|
- В хеш-таблице сначала выбирается бакет, затем удаление выполняется внутри короткой цепочки.
|
|||
|
|
- В BST удаление зависит от числа потомков: если потомок один или ноль, операция простая; если два — нужно найти преемника.
|
|||
|
|
|
|||
|
|
## Вывод
|
|||
|
|
|
|||
|
|
Для частых вставок и особенно частого поиска в реальной задаче чаще всего лучше подходит **хеш-таблица**.
|
|||
|
|
|
|||
|
|
Если важно получать данные в отсортированном виде, удобнее использовать **BST**.
|
|||
|
|
|
|||
|
|
**Связный список** подходит для маленьких объёмов данных или очень простых сценариев, но при большом числе записей он проигрывает по скорости поиска.
|