{ "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 }