# Лабораторная работа №1: Сравнительный анализ структур данных
---

## 1. Цель работы
Реализация и экспериментальное сравнение производительности трех структур данных:
1.  **Связный список (LinkedList)**
2.  **Хеш-таблица (HashTable)**
3.  **Бинарное дерево поиска (BST)**

Структуры реализованы в процедурной парадигме (без использования классов). Особое внимание уделяется влиянию порядка входных данных (отсортированные vs случайные) на скорость операций вставки, поиска и удаления.

## 2. Методика эксперимента

*   **Объем выборки:** $N = 10\,000$ записей (имя, телефон).
*   **Режимы входных данных:**
    *   *Случайный (Shuffled)* — имена перемешаны.
    *   *Отсортированный (Sorted)* — имена идут по алфавиту.
*   **Измеряемые метрики:**
    *   Время полной вставки $N$ элементов.
    *   Время 110 операций поиска (100 существующих + 10 несуществующих).
    *   Время 50 операций удаления.
*   **Инструментарий:** Замеры выполнены через `time.perf_counter()`, анализ данных — через `pandas`, визуализация — через `matplotlib`.
*   **Повторяемость:** Каждый тест запущен 5 раз для усреднения погрешности.

---

## 3. Результаты

### 3.1. Сводная таблица (Средние значения, сек)

| Структура | Режим | Вставка (N) | Поиск (110) | Удаление (50) |
| :--- | :--- | :--- | :--- | :--- |
| **HashTable** | Случайный | **0.011** | **0.0001** | **0.00006** |
| **HashTable** | Отсортированный | 0.010 | 0.0001 | 0.00006 |
| **BST** | Случайный | 0.049 | 0.0005 | 0.0003 |
| **BST** | Отсортированный | **29.91** | 0.093 | 0.106 |
| **LinkedList** | Случайный | 10.82 | 0.134 | 0.057 |
| **LinkedList** | Отсортированный | 6.79 | 0.059 | 0.035 |

### 3.2. Визуализация

![График производительности](data/plot.png)
*(На графике ось Y логарифмическая. Это необходимо, так как диапазон времен составляет от $10^{-4}$ до $30$ секунд).*

---

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

### 4.1. Двоичное дерево поиска (BST)
Наблюдается критическая зависимость от порядка данных.
*   **Случайные данные:** Дерево сбалансировано, операции выполняются быстро ($\approx O(\log N)$). Время вставки — 0.05 сек.
*   **Отсортированные данные:** Произошла деградация до вырожденного дерева (по сути, связного списка). Каждая вставка проходит до самого глубокого уровня. Время вставки составило **~30 секунд**.
*   **Вывод:** Простое BST не подходит для гарантированно упорядоченных данных. Для реальных систем требуется балансировка (AVL, Red-Black Trees).

### 4.2. Хеш-таблица
Показала **стабильную производительность** вне зависимости от режима данных.
*   Время вставки $\approx 0.01$ сек.
*   Время поиска $\approx 0.0001$ сек (в 1000 раз быстрее поиска в списке).
*   Это подтверждает теоретическую сложность $O(1)$ (в среднем). Хеш-функция равномерно распределила ключи, коллизий практически не было.

### 4.3. Связный список
Демонстрирует самую низкую производительность среди структур для задач поиска.
*   Вставка в случайном порядке занимает больше времени (10.8 сек), чем в отсортированном (6.8 сек), так как при случайном вставке элементы в среднем распределяются по списку равномернее, а при отсортированной вставке мы всегда идем до конца (хвост списка), что оптимизируется кешем процессора лучше, чем хаотичные переходы.
*   Поиск занимает $\approx 0.1$ сек ($O(N)$), что значительно медленнее хеш-таблицы.

---

## 5. Итоговые выводы

1.  **Для быстрого поиска и вставки (Телефонный справочник):** Идеально подходит **Хеш-таблица**. Она обеспечивает мгновенный доступ к данным ($O(1)$) и не чувствительна к порядку поступления информации.
2.  **Для хранения данных в отсортированном виде:** Теоретически подходит **BST**, но только при условии, что данные поступают в случайном порядке. Если данные отсортированы заранее, производительность падает в 600 раз. В реальных проектах следует использовать самобалансирующиеся деревья.
3.  **Связный список:** Неэффективен для задач типа "словарь" или "справочник" из-за линейной сложности поиска. Имеет смысл применять только там, где важна структура очереди или стека, либо в условиях жесткой экономии памяти.