{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0c973489-075d-42ac-a28f-f8d8d954a0da",
   "metadata": {},
   "source": [
    "# Анализ результатов\n",
    "\n",
    "## Предложенные вопросы\n",
    "\n",
    "- Как порядок входных данных влияет на скорость вставки в BST (деградация до O(n) на отсортированных данных)?\n",
    "- Почему хеш-таблица почти не чувствительна к порядку?\n",
    "- Почему связный список всегда медленен при поиске?\n",
    "- Как удаление работает в каждой структуре?\n",
    "- Вывод: какую структуру и для каких задач (частые вставки, частый поиск, необходимость получать данные в порядке) стоит выбирать в реальной жизни?\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a265cc14-95ff-47ae-a346-ac38cb2a323e",
   "metadata": {},
   "source": [
    "## Выводы\n",
    "\n",
    "### 1) Как порядок входных данных влияет на скорость вставки в BST?\n",
    "\n",
    "Порядок отличается очень сильно. В обычном случае сложность равна **O(log n)**, а в худшем случае (как раз на отсортированных данных) – **O(n)**.  \n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "950c5e97-12e9-4225-a91e-b8289fdfb5e6",
   "metadata": {},
   "source": [
    "### 2) Почему хеш-таблица почти не чувствительна к порядку?\n",
    "\n",
    "Это происходит из‑за особенностей записи данных в память. Хеш-таблица вычисляет номер строки (корзины) по математической формуле, поэтому любой элемент можно найти за **O(1)** в среднем. Порядок поступления записей не влияет на расчёт индекса.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5f6059bf-e99a-4b14-869c-32fb44b092fa",
   "metadata": {},
   "source": [
    "### 3) Почему связный список всегда медленен при поиске?\n",
    "\n",
    "Это происходит из‑за способа записи. Доступ к следующему элементу возможен только последовательным перебором, равным номеру искомой позиции. Сложность поиска – **O(n)**.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "77ddd385-a50d-4ab6-b761-477460529e9d",
   "metadata": {},
   "source": [
    "### 4) Как удаление работает в каждой структуре?\n",
    "\n",
    "- **Связный список**  \n",
    "  - Если список пустой → возвращаем `None`.  \n",
    "  - Если удаляем голову → новой головой становится следующий элемент.  \n",
    "  - Если удаляем промежуточный элемент – ищем нужный узел, затем у предыдущего узла меняем ссылку на следующий после удаляемого.\n",
    "\n",
    "- **Хеш-таблица**  \n",
    "  Реализация вычисляет номер корзины через хеш-ключ, затем использует функции связного списка для работы внутри корзины. Таким образом, удаление в хеш-таблице наследует логику удаления из связного списка, но применяется только к элементам одной корзины.\n",
    "\n",
    "- **Бинарное дерево (BST)**  \n",
    "  Рассматриваются 4 случая (логика похожа на связный список, но с учётом двух потомков):  \n",
    "  - Если дерево пустое → вернуть `None`.  \n",
    "  - Если удаляемый элемент меньше корня → спуститься в левую ветвь.  \n",
    "  - Если больше корня → спуститься в правую ветвь.  \n",
    "  - Если у удаляемого узла два потомка – находим преемника (самый левый узел в правом поддереве), копируем его данные в удаляемый узел и удаляем преемника.  \n",
    "  При нахождении элемента ссылка от родителя к удаляемому узлу заменяется на ссылку на соответствующего потомка (левый или правый).\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "97b09bb6-e8ef-486e-9cdd-fc37b19bfeb2",
   "metadata": {},
   "source": [
    "### 5) Какую структуру и для каких задач стоит выбирать в реальной жизни?\n",
    "\n",
    "- **Для частых вставок и поиска элементов** – лучше всего использовать **хеш-таблицу**, так как добавление происходит за счёт математического вычисления индекса, а не последовательного перебора.  \n",
    "- **Если нужны упорядоченные данные** (например, вывод записей в алфавитном порядке) – подходит **двоичное дерево поиска** (BST) благодаря свойству in‑order обхода.  \n",
    "- **Связный список** неэффективен для больших объёмов данных.\n",
    "\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3b242f54-fd27-4f6e-8a31-9b3a6bee5f59",
   "metadata": {},
   "source": [
    "## Дополнительные числовые результаты\n",
    "\n",
    "\n",
    "\n",
    "1. **Связный список:**  \n",
    "   - Вставка: O(n) → ~0.25 с, порядок данных не влияет.  \n",
    "   - Поиск: O(n) → очень медленно (~0.5 с), порядок не влияет.  \n",
    "   - Удаление: O(n) → медленно.\n",
    "\n",
    "2. **Хеш-таблица:**  \n",
    "   - Вставка: O(1) в среднем → ~0.008 с, порядок данных не влияет.  \n",
    "   - Поиск: O(1) → ~0.002 с, самый быстрый.  \n",
    "   - Удаление: O(1) → ~0.002 с.\n",
    "\n",
    "3. **Двоичное дерево поиска:**  \n",
    "   - На случайных данных: O(log n) → вставка ~0.018 с, поиск ~0.0015 с, удаление ~0.0016 с.  \n",
    "   - На отсортированных данных: дерево вырождается в линейный список → вставка ~2.3 с, поиск и удаление также становятся O(n) (на графиках виден рост времени).\n",
    "\n",
    "**ИТОГОВЫЙ ВЫВОД:**  \n",
    "- Для частого поиска, вставки и удаления – лучший выбор **хеш-таблица**.  \n",
    "- Если данные поступают в отсортированном порядке – BST не подходит из‑за деградации.  \n",
    "- Если нужна частая выдача записей в алфавитном порядке и данные случайны – BST хорош.  \n",
    "- Связный список неэффективен для больших объёмов."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1b39f136-0c95-46f0-b794-7136232bcd3c",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
