2026-rff_mp/anikinvd/docs/report-1-st.md

9.0 KiB
Raw Blame History

Лабораторная работа: Сравнение структур данных для телефонного справочника

1. Введение

В рамках работы были реализованы три структуры данных «с нуля» на языке Python без использования классов, в процедурной парадигме:

  • Связный список — узлы хранятся в виде словарей {'name', 'phone', 'next'}.
  • Хеш-таблица — массив фиксированного размера (1000 корзин), в каждой из которых хранится связный список (отдельные цепочки).
  • Двоичное дерево поиска (BST) — узлы имеют поля left, right.

Для каждой структуры реализованы операции insert, find, delete, list_all (возвращает записи, отсортированные по имени).

Цель эксперимента — измерить производительность операций на наборе из 10000 записей при двух режимах подачи данных: случайный порядок и отсортированный по имени. Каждый опыт повторялся 5 раз, результаты усреднены. Измерялось общее время:

  • вставки всех 10000 записей;
  • поиска 110 записей (100 существующих + 10 несуществующих);
  • удаления 50 случайных записей.

2. Результаты измерений

В таблице приведены средние значения времени (в секундах) для каждой структуры и режима.

Структура Режим Вставка (с) Поиск (с) Удаление (с)
LinkedList случайный 4.1342 0.0282 0.0138
LinkedList сортир. 3.7426 0.0248 0.0116
HashTable случайный 0.00940 0.000075 0.000037
HashTable сортир. 0.00915 0.000070 0.000032
BST случайный 0.02396 0.000216 0.000126
BST сортир. 9.1117 0.0796 0.0512

Графическое представление результатов приведено на рисунке performance_comparison.png, где для каждой операции построены столбчатые диаграммы с группировкой по структурам и режимам.

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

3.1. Влияние порядка данных на BST

Двоичное дерево поиска чувствительно к порядку поступления ключей. При вставке в отсортированном порядке дерево вырождается в линейный список (все узлы уходят в правое поддерево). Высота становится O(n), что приводит к резкому падению производительности:

  • Вставка на отсортированных данных (9.11 с) медленнее в 380 раз, чем на случайных (0.024 с).
  • Поиск замедляется в ~370 раз, удаление — в ~406 раз.

Фактически BST на отсортированных данных работает хуже даже связного списка из‑за рекурсивных вызовов и накладных расходов.

3.2. Устойчивость хеш-таблицы к порядку

Хеш-функция равномерно распределяет имена по корзинам вне зависимости от порядка поступления. Поэтому времена вставки, поиска и удаления практически идентичны для случайного и отсортированного режимов:

  • Вставка: 0.00940 с (случ.) vs 0.00915 с (сорт.) — разница в пределах погрешности.
  • Поиск и удаление также стабильны.

Средняя сложность O(1) подтверждается на практике.

3.3. Связный список — линейная сложность на всех операциях

Связный список не обеспечивает прямого доступа к элементам. Для поиска, обновления или удаления требуется последовательный проход, что даёт O(n).

  • Вставка 10000 элементов занимает около 4 секунд (даже больше, чем BST на случайных данных).
  • Поиск (~0.028 с) на порядок медленнее, чем в хеш-таблице и BST на случайных данных.
  • Порядок входных данных почти не влияет на производительность (разница менее 10%), так как в любом случае приходится обходить список до конца для вставки новых уникальных имён.

3.4. Сравнение удаления

  • Связный список: удаление требует сначала найти элемент (O(n)), затем переставить ссылки. Время ~0.0120.014 с, что близко ко времени поиска.
  • Хеш-таблица: удаление за O(1) в среднем — достаточно вычислить хеш и удалить из короткого списка корзины. Время ~0.000030.00004 с.
  • BST: на случайных данных удаление очень быстрое (0.000126 с) благодаря логарифмической высоте. На отсортированных данных время возрастает до 0.051 с (деградация до O(n)).

4. Выводы и рекомендации

На основе полученных результатов можно сделать следующие выводы о применимости структур в реальных задачах:

  • Хеш-таблица — лучший выбор, когда требуется максимальная скорость всех операций (вставка, поиск, удаление) и не важен порядок хранения. Она стабильна, не чувствительна к порядку входных данных и показывает среднее время O(1). Идеальна для реализации словарей, кэшей, индексов по ключу.

  • Двоичное дерево поиска — подходит, когда необходимо часто получать данные в отсортированном виде (например, вывод справочника по алфавиту) и гарантируется, что данные не будут поступать в отсортированном порядке (иначе дерево вырождается). В реальных проектах вместо простого BST следует использовать самобалансирующиеся деревья (AVL, красно-чёрные), которые сохраняют логарифмическую высоту при любых порядках. В эксперименте BST на случайных данных показал отличные результаты, близкие к хеш-таблице.

  • Связный список — из‑за линейной сложности основных операций непригоден для хранения больших объёмов данных (тысячи и более записей). Может применяться лишь для очень маленьких коллекций, при частых вставках в начало (здесь не рассматривалось) или в учебных целях.

Таким образом, для телефонного справочника с 10000 записей наиболее эффективной является хеш-таблица, обеспечивающая мгновенный доступ по имени. Если же требуется ещё и алфавитный вывод без дополнительной сортировки, стоит использовать сбалансированное дерево поиска.