2026-rff_mp/nikolaevda/docs/report_laba1.ipynb
2026-05-16 21:06:11 +03:00

246 lines
14 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "7cbca316",
"metadata": {},
"outputs": [],
"source": [
"{\n",
" \"cells\": [\n",
" {\n",
" \"cell_type\": \"markdown\",\n",
" \"id\": \"start\",\n",
" \"metadata\": {},\n",
" \"source\": [\n",
" \"# Отчёт по лабораторной работе\\n\",\n",
" \"## Тема: Сравнение производительности структур данных для телефонного справочника\\n\",\n",
" \"\\n\",\n",
" \"---\"\n",
" ]\n",
" },\n",
" {\n",
" \"cell_type\": \"markdown\",\n",
" \"id\": \"goal\",\n",
" \"metadata\": {},\n",
" \"source\": [\n",
" \"## 1. Цель работы\\n\",\n",
" \"\\n\",\n",
" \"Реализовать три различные структуры данных «с нуля», применить их для хранения записей телефонного справочника и экспериментально сравнить производительность основных операций (вставка, поиск, удаление).\\n\",\n",
" \"\\n\",\n",
" \"---\"\n",
" ]\n",
" },\n",
" {\n",
" \"cell_type\": \"markdown\",\n",
" \"id\": \"conditions\",\n",
" \"metadata\": {},\n",
" \"source\": [\n",
" \"## 2. Условия эксперимента\\n\",\n",
" \"\\n\",\n",
" \"| Параметр | Значение |\\n\",\n",
" \"|----------|----------|\\n\",\n",
" \"| Общее число записей | 10 000 |\\n\",\n",
" \"| Каждый замер повторялся | 5 раз |\\n\",\n",
" \"| Количество существующих записей для поиска | 100 |\\n\",\n",
" \"| Количество несуществующих записей для поиска | 10 |\\n\",\n",
" \"| Количество элементов для удаления | 50 |\\n\",\n",
" \"| Размер хеш-таблицы | 2003 (простое число) |\\n\",\n",
" \"| Режимы тестирования | Случайный / Отсортированный |\\n\",\n",
" \"\\n\",\n",
" \"---\"\n",
" ]\n",
" },\n",
" {\n",
" \"cell_type\": \"markdown\",\n",
" \"id\": \"graphs\",\n",
" \"metadata\": {},\n",
" \"source\": [\n",
" \"## 3. Практические графики\\n\",\n",
" \"\\n\",\n",
" \"### Информация о тестировании\\n\",\n",
" \"- Общее число записей: 10 000\\n\",\n",
" \"- Каждый замер повторялся: 5 раз\\n\",\n",
" \"- Количество существующих записей для случайного поиска: 100\\n\",\n",
" \"- Количество несуществующих записей для поиска: 10\\n\",\n",
" \"- Количество элементов для удаления: 50\\n\",\n",
" \"\\n\",\n",
" \"![График вставки](graphs.png)\\n\",\n",
" \"\\n\",\n",
" \"**Рис. 1 Тестирование вставки (логарифмическая шкала)**\\n\",\n",
" \"\\n\",\n",
" \"---\"\n",
" ]\n",
" },\n",
" {\n",
" \"cell_type\": \"markdown\",\n",
" \"id\": \"analysis_bst\",\n",
" \"metadata\": {},\n",
" \"source\": [\n",
" \"## 4. Анализ результатов\\n\",\n",
" \"\\n\",\n",
" \"### Как порядок входных данных влияет на скорость вставки в BST (деградация до O(n) на отсортированных данных)?\\n\",\n",
" \"\\n\",\n",
" \"По определению, при вставке отсортированных данных, структура бинарного дерева поиска вырождается в связный список.\\n\",\n",
" \"\\n\",\n",
" \"**Результаты тестирования:**\\n\",\n",
" \"- На случайных данных: время вставки ~0.037 секунд\\n\",\n",
" \"- На отсортированных данных: время вставки ~18.34 секунд (деградация в ~470 раз!)\\n\",\n",
" \"\\n\",\n",
" \"Заметим, что при случайных данных скорость вставки в бинарное дерево почти лишь немного уступает по скорости хеш-таблице. При отсортированных данных дерево фактически превращается в связный список, и из-за рекурсивной реализации вставки бинарное дерево становится даже медленнее связного списка.\\n\",\n",
" \"\\n\",\n",
" \"---\"\n",
" ]\n",
" },\n",
" {\n",
" \"cell_type\": \"markdown\",\n",
" \"id\": \"analysis_hash\",\n",
" \"metadata\": {},\n",
" \"source\": [\n",
" \"### Почему хеш-таблица почти не чувствительна к порядку?\\n\",\n",
" \"\\n\",\n",
" \"Хеш-таблица не чувствительна к порядку данных, так как:\\n\",\n",
" \"1. Использует для распределения элементов хеш-значения данных (сложность операции одинакова для любых однотипных данных)\\n\",\n",
" \"2. Хеш-функция равномерно распределяет ключи по корзинам независимо от их порядка\\n\",\n",
" \"3. Вставка в конкретную корзину не зависит от соседних элементов\\n\",\n",
" \"\\n\",\n",
" \"**Экспериментальное подтверждение:**\\n\",\n",
" \"- Случайный порядок: вставка = 0.0369 сек, поиск = 0.000355 сек\\n\",\n",
" \"- Отсортированный порядок: вставка = 0.0356 сек, поиск = 0.000380 сек\\n\",\n",
" \"\\n\",\n",
" \"Разница незначительна и находится в пределах погрешности измерений.\\n\",\n",
" \"\\n\",\n",
" \"---\"\n",
" ]\n",
" },\n",
" {\n",
" \"cell_type\": \"markdown\",\n",
" \"id\": \"analysis_list\",\n",
" \"metadata\": {},\n",
" \"source\": [\n",
" \"### Почему связный список всегда медленен при поиске?\\n\",\n",
" \"\\n\",\n",
" \"Операция поиска в связном списке имеет линейную сложность **O(n)** независимо от порядка данных, так как:\\n\",\n",
" \"- Нет индексов для прямого доступа\\n\",\n",
" \"- Нет сортировки, позволяющей применять бинарный поиск\\n\",\n",
" \"- Приходится последовательно перебирать все элементы до найденного\\n\",\n",
" \"\\n\",\n",
" \"| Структура | Сложность поиска | Время поиска (случайный) |\\n\",\n",
" \"|-----------|-----------------|--------------------------|\\n\",\n",
" \"| Связный список | O(n) | 0.0427 сек |\\n\",\n",
" \"| Хеш-таблица | O(1) средняя | 0.000355 сек |\\n\",\n",
" \"| BST (случайный) | O(log n) | 0.000527 сек |\\n\",\n",
" \"\\n\",\n",
" \"---\"\n",
" ]\n",
" },\n",
" {\n",
" \"cell_type\": \"markdown\",\n",
" \"id\": \"analysis_delete\",\n",
" \"metadata\": {},\n",
" \"source\": [\n",
" \"### Как удаление работает в каждой структуре?\\n\",\n",
" \"\\n\",\n",
" \"#### Связный список\\n\",\n",
" \"Находим элемент перед удаляемым элементом и заменяем его поле `next` на `next.next`:\\n\",\n",
" \"```python\\n\",\n",
" \"current = head\\n\",\n",
" \"while current['next'] is not None:\\n\",\n",
" \" if current['next']['name'] == name:\\n\",\n",
" \" current['next'] = current['next']['next']\\n\",\n",
" \" return head\\n\",\n",
" \" current = current['next']\\n\",\n",
" \"```\\n\",\n",
" \"\\n\",\n",
" \"#### Двоичное дерево поиска\\n\",\n",
" \"После того, как мы нашли узел, который необходимо удалить, возможны три случая:\\n\",\n",
" \"\\n\",\n",
" \"**Случай 1:** У удаляемого узла нет детей → просто удаляем узел.\\n\",\n",
" \"\\n\",\n",
" \"**Случай 2:** У удаляемого узла есть только один ребёнок → ребёнок занимает место удалённого узла.\\n\",\n",
" \"\\n\",\n",
" \"**Случай 3:** У удаляемого узла есть оба ребёнка → находим минимальный элемент в правом поддереве (самый левый узел) и заменяем им удаляемый узел.\\n\",\n",
" \"\\n\",\n",
" \"#### Хеш-таблица\\n\",\n",
" \"1. Вычисляем хеш-индекс: `index = hash_func(name, len(buckets))`\\n\",\n",
" \"2. Находим нужную корзину: `buckets[index]`\\n\",\n",
" \"3. Удаляем элемент из связного списка в этой корзине\\n\",\n",
" \"\\n\",\n",
" \"**Сравнение времени удаления:**\\n\",\n",
" \"\\n\",\n",
" \"| Структура | Время удаления (случайный) | Сложность |\\n\",\n",
" \"|-----------|---------------------------|-----------|\\n\",\n",
" \"| Связный список | 0.0341 сек | O(n) |\\n\",\n",
" \"| Хеш-таблица | 0.00018 сек | O(1) средняя |\\n\",\n",
" \"| BST | 0.0793 сек | O(log n) средняя |\\n\",\n",
" \"\\n\",\n",
" \"---\"\n",
" ]\n",
" },\n",
" {\n",
" \"cell_type\": \"markdown\",\n",
" \"id\": \"conclusion\",\n",
" \"metadata\": {},\n",
" \"source\": [\n",
" \"## 5. Вывод\\n\",\n",
" \"\\n\",\n",
" \"Мы реализовали и протестировали три различные структуры хранения данных: связный список, хеш-таблицу и двоичное дерево поиска. Сравнили скорость операций вставки, удаления и поиска для каждой структуры.\\n\",\n",
" \"\\n\",\n",
" \"### Итоговая таблица производительности (случайный порядок):\\n\",\n",
" \"\\n\",\n",
" \"| Структура | Вставка (сек) | Поиск (сек) | Удаление (сек) |\\n\",\n",
" \"|-----------|---------------|-------------|----------------|\\n\",\n",
" \"| Связный список | 4.6031 | 0.0427 | 0.0341 |\\n\",\n",
" \"| Хеш-таблица | **0.0369** | **0.00036** | **0.00018** |\\n\",\n",
" \"| BST | 0.0369 | 0.00053 | 0.0793 |\\n\",\n",
" \"\\n\",\n",
" \"### Рекомендации по выбору структуры данных:\\n\",\n",
" \"\\n\",\n",
" \"1. **Хеш-таблица** лучший выбор для телефонного справочника:\\n\",\n",
" \" - Не важен порядок хранения и извлечения данных\\n\",\n",
" \" - Требуется максимальная скорость поиска и вставки\\n\",\n",
" \" - Результат: **победитель по всем параметрам**\\n\",\n",
" \"\\n\",\n",
" \"2. **Двоичное дерево поиска** выбираем, если:\\n\",\n",
" \" - Нужно хранить данные с возможностью быстрого отсортированного обхода\\n\",\n",
" \" - Данные поступают в случайном порядке (иначе будет деградация)\\n\",\n",
" \" - Можно использовать сбалансированную версию (AVL, красно-чёрное)\\n\",\n",
" \"\\n\",\n",
" \"3. **Связный список** выбираем, если:\\n\",\n",
" \" - Нужно хранить данные в порядке поступления (очередь, стек)\\n\",\n",
" \" - Объём данных очень маленький (< 100 записей)\\n\",\n",
" \" - Простота реализации важнее производительности\\n\",\n",
" \"\\n\",\n",
" \"---\\n\",\n",
" \"\\n\",\n",
" \"**Заключение:** Для реализации телефонного справочника оптимальнее всего использовать **хеш-таблицу**, так как она обеспечивает наилучшую производительность для всех операций и не чувствительна к порядку входных данных.\"\n",
" ]\n",
" }\n",
" ],\n",
" \"metadata\": {\n",
" \"kernelspec\": {\n",
" \"display_name\": \"Python 3\",\n",
" \"language\": \"python\",\n",
" \"name\": \"python3\"\n",
" },\n",
" \"language_info\": {\n",
" \"name\": \"python\",\n",
" \"version\": \"3.14.0\"\n",
" }\n",
" },\n",
" \"nbformat\": 4,\n",
" \"nbformat_minor\": 5\n",
"}"
]
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}