# Отчёт по лабораторной работе «Структуры данных»

## Цель работы
Реализовать три структуры данных (связный список, хеш-таблицу, двоичное дерево поиска) «с нуля» и экспериментально сравнить их производительность на операциях вставки, поиска и удаления записей телефонного справочника.

## Реализованные структуры
- **Связный список (LinkedList)** – элементы хранятся в узлах со ссылкой на следующий.  
- **Хеш-таблица (HashTable)** – массив корзин фиксированного размера (997), каждая корзина – связный список.  
- **Двоичное дерево поиска (BST)** – узлы содержат ключ (имя) и ссылки на левое/правое поддеревья.

Все операции реализованы вручную без использования классов.

## Методика эксперимента
- **Объём данных**: N = 10 000 записей вида `User_XXXXX` → случайный телефон.  
- **Режимы ввода**: случайный порядок и отсортированный по имени.  
- **Действия**:
  1. Вставка всех записей.
  2. Поиск 100 существующих + 10 несуществующих имён.
  3. Удаление 50 случайных записей.
- **Повторения**: каждый эксперимент выполнен 5 раз, зафиксировано время (`time.perf_counter`).  
- **Сбор результатов**: усреднение по 5 повторениям.

## Результаты измерений
### Среднее время операций (секунды)

| Структура   | Режим       | Вставка  | Поиск    | Удаление |
|-------------|-------------|----------|----------|----------|
| LinkedList  | случайный   | 4.0979   | 0.0278   | 0.0134   |
| LinkedList  | отсортир.   | 3.8044   | 0.0251   | 0.0110   |
| HashTable   | случайный   | 0.0101   | 0.000080 | 0.000044 |
| HashTable   | отсортир.   | 0.0098   | 0.000078 | 0.000037 |
| BST         | случайный   | 0.0229   | 0.000191 | 0.000113 |
| BST         | отсортир.   | 9.1518   | 0.0824   | 0.0506   |

*Полные замеры всех 5 повторений сохранены в `experiment_results.csv`.*

### График сравнения
![Сравнение производительности](performance_comparison.png)

## Анализ результатов

### Влияние порядка данных на BST
При вставке отсортированных данных BST вырождается в линейный список (высота ≈ N).  
Время вставки возрастает с **0.023 с** (случайный) до **9.15 с** (отсортированный) – деградация в **~400 раз**.  
Поиск и удаление замедляются аналогично.

### Устойчивость хеш-таблицы
Хеш-функция равномерно распределяет ключи независимо от порядка.  
Время вставки в случайном (0.0101 с) и отсортированном (0.0098 с) режимах практически одинаково, как и поиск (~0.00008 с).

### Медлительность связного списка
Поиск (O(n)) на 10 000 элементов занимает ~0.027 с, что на два порядка медленнее хеш-таблицы.  
Вставка в конец также требует прохода по всему списку (~4 с).

### Удаление
Наиболее эффективно в хеш-таблице (≈0.00004 с).  
В BST на случайных данных удаление быстрое (0.00011 с), но на отсортированных деградирует до 0.05 с.  
В списке удаление (0.013 с) сравнимо с поиском.

## Выводы и рекомендации

1. **Хеш-таблица** – оптимальный выбор для задач, где нужен быстрый доступ по ключу, а порядок данных не важен.  
2. **Двоичное дерево поиска** – подходит, если требуется получать записи в отсортированном порядке **и** данные поступают в случайном порядке. При отсортированных входных данных необходима балансировка (AVL, красно-чёрное дерево).  
3. **Связный список** – неэффективен для больших объёмов; может применяться только в учебных целях или при очень маленьких коллекциях.

В реальных проектах для справочников и словарей следует выбирать хеш-таблицы или сбалансированные деревья в зависимости от необходимости упорядоченного вывода.