2026-rff_mp/shalovsa/lab1/docs/report (1).md
2026-05-11 17:25:51 +03:00

8.2 KiB
Raw Blame History

Отчёт: Задание 1 — Структуры данных

Цель работы

Разработать три структуры данных «с нуля» в процедурном стиле (без ООП), применить их для хранения записей телефонной книги и провести экспериментальное сравнение производительности ключевых операций.

Структуры данных:

  • Связный список (LinkedList)
  • Хеш-таблица (HashTable)
  • Двоичное дерево поиска (BST)

Реализация

Основные технические решения

1. Связный список

Узел реализован как Python-словарь: {'name': 'Имя', 'phone': '123', 'next': None}.

Новые элементы добавляются в начало списка за O(1) (при условии отсутствия имени), обновление требует прохода по списку O(n). Поиск и удаление работают за линейное время из-за отсутствия прямого доступа по индексу.

2. Хеш-таблица

Фиксированный массив на 256 корзин. Каждая корзина — указатель на связный список (метод цепочек). Хеш-функция: стандартный hash(name) % size. Среднее время операций O(1), при коллизиях — O(k), где k — длина цепочки.

3. Двоичное дерево поиска (BST)

Узел: {'name': 'Имя', 'phone': '123', 'left': None, 'right': None}. Сравнение ключей — лексикографическое по полю name. Вставка и поиск реализованы итеративно. Удаление — рекурсивное с заменой на минимальный узел правого поддерева. Обход в глубину даёт отсортированный список.


Экспериментальная часть

Условия проведения замеров

Параметр Значение
Количество записей (N) 10 000
Количество замеров на операцию 5
Поисковых запросов 110 (100 существующих + 10 отсутствующих)
Удалений 50
Размер хеш-таблицы 256 корзин

Два набора данных:

  • records_shuffled — случайный порядок записей
  • records_sorted — упорядоченный по имени (алфавитный порядок)

Результаты

Среднее время выполнения (секунды)

Структура Режим Вставка (с) Поиск 110 (с) Удаление 50 (с)
LinkedList случайный 2.541985 0.034289 0.020349
LinkedList сортированный 2.208557 0.025340 0.016424
HashTable случайный 0.018235 0.000214 0.000120
HashTable сортированный 0.016163 0.000207 0.000124
BST случайный 0.017192 0.000145 0.000104
BST сортированный 3.854338 0.033498 0.045823

Визуализация

Сравнение по операциям

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


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

1. Связный список — стабильно низкая скорость

Вставка требует ~2.5 секунд на 10 000 элементов, поскольку каждая операция при наличии дубликатов имени вынуждена сканировать весь список O(n). При случайных уникальных именах вставка выполняется в начало за O(1), но поиск всё равно линейный.

Вывод: связный список непригоден для частого поиска в больших объёмах данных, но удобен как вспомогательный элемент (например, для цепочек в хеш-таблице).

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

Хеш-таблица продемонстрировала практически идентичные результаты в обоих режимах:

  • Вставка: ~0.017 с (быстрее списка в ~150 раз)
  • Поиск: ~0.0002 с (быстрее списка в ~160 раз)

Хеш-функция равномерно распределяет ключи независимо от порядка их поступления, поэтому производительность остаётся стабильной.

3. BST катастрофически деградирует на упорядоченных данных

Наиболее показательный результат эксперимента:

Случайный Сортированный Ухудшение
BST insert 0.017 с 3.854 с ×225
BST find 0.000145 с 0.033 с ×231

Причина: при вставке отсортированных данных дерево вырождается в линейный список — каждый новый элемент оказывается больше предыдущего и помещается только в правую ветку. Высота дерева становится O(n) вместо O(log n), что превращает все операции в линейные.

4. Операция delete

На случайных данных BST удаляет за ~0.0001 с (логарифмическая сложность). На сортированных — ~0.046 с (линейная деградация). HashTable показывает стабильные ~0.00012 с независимо от порядка.


Выводы и практические рекомендации

Выбор структуры в зависимости от задачи

Сценарий Рекомендация
Частый поиск по ключу HashTable или BST (случайный порядок)
Данные поступают упорядоченно HashTable (BST непригоден)
Требуется отсортированный вывод BST (обход даёт порядок за O(n))
Интенсивные вставки/удаления + поиск HashTable
Ограниченный объём данных, простота LinkedList (до сотен элементов)
Диапазонные запросы (например, AM) BST

Теоретическая сложность операций

Структура Insert Find Delete Обход (отсорт.)
LinkedList O(n) O(n) O(n) O(n log n)
HashTable O(1) в среднем O(1) в среднем O(1) в среднем O(n log n)
BST (сбалансированный) O(log n) O(log n) O(log n) O(n)
BST (вырожденный) O(n) O(n) O(n) O(n)

Ключевой вывод

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