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**.
|
||
|
||
**Связный список** подходит для маленьких объёмов данных или очень простых сценариев, но при большом числе записей он проигрывает по скорости поиска.
|