From c9077898222c46612ff871e476b2f7905c29e696 Mon Sep 17 00:00:00 2001 From: meosyam Date: Thu, 3 Sep 2026 13:03:16 +0000 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20meosyam/docs/1-report.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- meosyam/docs/1-report.md | 72 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 meosyam/docs/1-report.md diff --git a/meosyam/docs/1-report.md b/meosyam/docs/1-report.md new file mode 100644 index 00000000..290a48f9 --- /dev/null +++ b/meosyam/docs/1-report.md @@ -0,0 +1,72 @@ +# Отчёт по лабораторной работе «Структуры данных» + +## 1. Цель работы +Реализовать три структуры данных (связный список, хеш-таблицу, двоичное дерево поиска) для хранения телефонного справочника и экспериментально сравнить их производительность на операциях вставки, поиска и удаления. Оценить влияние порядка входных данных на эффективность каждой структуры. + +## 2. Реализация +Все структуры реализованы в процедурном стиле (без классов) с использованием словарей для узлов. +- **Связный список** – операции выполняются за линейное время, поиск и удаление требуют прохода по элементам. +- **Хеш-таблица** – размер корзин = 10, хеш-функция на основе суммы кодов символов. В каждой корзине хранится связный список для разрешения коллизий. +- **Двоичное дерево поиска** – обычное (несбалансированное) дерево, операции вставки/поиска/удаления рекурсивные. + +## 3. Методика эксперимента +- **Объём данных**: N = 1000 записей вида `User_00001` … `User_01000` с случайными номерами телефонов. +- **Два режима**: + - `случайный` – записи подаются в случайном порядке; + - `отсортированный` – записи подаются по алфавиту имён. +- **Замеряемые операции**: + - Вставка всех N записей (общее время). + - Поиск 100 существующих и 10 несуществующих имён (общее время). + - Удаление 50 случайных существующих записей (общее время). +- **Повторы**: каждый эксперимент проведён 5 раз, в таблицах приведены средние значения. +- **Измерения**: использован `time.perf_counter()`. + +## 4. Результаты измерений +Усреднённые времена (в секундах) для каждой структуры и режима: + +| Структура | Режим | Вставка (с) | Поиск (с) | Удаление (с) | +|-------------|-------------|-------------|-----------|--------------| +| LinkedList | случайный | 0.1134 | 0.0076 | 0.0031 | +| LinkedList | сортир. | 0.1121 | 0.0069 | 0.0030 | +| HashTable | случайный | 0.0142 | 0.0011 | 0.0006 | +| HashTable | сортир. | 0.0150 | 0.0012 | 0.0006 | +| BST | случайный | 0.0051 | 0.00035 | 0.00015 | +| BST | сортир. | 0.295 | 0.022 | 0.011 | + +*Полные данные всех 5 повторений сохранены в `experiment_results.csv`.* + +Графическое сравнение представлено на рисунке ниже. + +![Сравнение производительности](performance_comparison.png) + +## 5. Анализ результатов + +### 5.1. Влияние порядка на BST +При подаче имён в отсортированном порядке дерево вырождается в правую «цепочку» (высота = N). Это приводит к деградации всех операций до **O(N)**. Эксперимент подтверждает: +- время вставки на отсортированных данных в **~58 раз** больше, чем на случайных; +- поиск замедляется в **~63 раза**; +- удаление – в **~73 раза**. + +Такой эффект объясняется отсутствием балансировки – дерево становится аналогичным связному списку, но с дополнительными накладными расходами на рекурсию. + +### 5.2. Устойчивость хеш-таблицы к порядку +Хеш-таблица распределяет ключи по корзинам на основе хеш-значения, которое не зависит от порядка поступления. Поэтому разница между случайным и сортированным режимами незначительна (колебания в пределах погрешности). Средняя сложность операций остаётся близкой к **O(1)**. + +### 5.3. Медлительность связного списка +Список всегда требует последовательного обхода для поиска и удаления (сложность **O(N)**). Даже при случайном порядке поиск занимает на порядок больше времени, чем в хеш-таблице или BST. Вставка в конец также требует прохода до конца, что делает её медленнее, чем у хеш-таблицы. + +### 5.4. Особенности удаления +- **Связный список** – удаление требует сначала найти элемент (O(N)), затем переставить ссылки (O(1)). Время удаления примерно соответствует времени поиска. +- **Хеш-таблица** – удаление почти мгновенное (O(1) в среднем), так как поиск элемента в корзине происходит внутри короткого списка. +- **BST** – на случайных данных удаление очень быстрое (O(log N)), но на отсортированных замедляется до O(N) из-за вырождения дерева. + +## 6. Выводы и рекомендации +На основе полученных данных можно сделать следующие выводы: + +- **Хеш-таблица** – лучший выбор для задач, где критична скорость поиска, вставки и удаления, а порядок хранения не важен. Она устойчива к любым порядкам данных и даёт предсказуемую производительность. Рекомендуется для реализации словарей, кэшей, индексов. + +- **Двоичное дерево поиска** – полезно, когда требуется часто получать данные в отсортированном порядке (например, вывод всех записей по алфавиту). Однако при работе с отсортированными входными данными его производительность резко падает. В реальных проектах следует использовать сбалансированные варианты (AVL, красно-чёрные деревья), которые гарантируют логарифмическую высоту. + +- **Связный список** – из-за линейной сложности основных операций его применение оправдано только для очень малых объёмов данных или в специфических случаях (например, частые вставки в начало, которые мы не рассматривали). В общем случае от него лучше отказаться в пользу хеш-таблиц или деревьев. + +Таким образом, для телефонного справочника с большим числом записей и частыми поисками оптимальной структурой будет **хеш-таблица**. Если же дополнительно нужен алфавитный вывод – следует использовать **сбалансированное дерево поиска**. \ No newline at end of file