\input{preambule.tex} \begin{document} % --- ТИТУЛЬНЫЙ ЛИСТ (упрощенно) --- \begin{titlepage} \centering МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РФ \\ «Национальный исследовательский Нижегородский государственный университет им. Н.И. Лобачевского» \\ \vspace{4cm} \Large ОТЧЕТ К ЛАБОРАТОРНОЙ РАБОТЕ \\ \vspace{1cm} \large «Реализация и экспериментальное сравнение базовых структур данных на примере телефонного справочника» \\ \vspace{4cm} \flushright Выполнил: студент В. В. Пронин \\ Преподаватель: Н. С. Морозов \\ \vfill Нижний Новгород \\ 2024 \end{titlepage} \newpage \tableofcontents \newpage \section{Введение} Эффективность программных систем во многом определяется выбором способов организации данных в оперативной памяти. Задача разработки телефонного справочника является классическим примером, требующим баланса между скоростью вставки новых записей, поиском по ключу и эффективным удалением. В рамках данной работы исследуются три фундаментальные структуры данных, реализованные «с нуля» в процедурной парадигме программирования на языке Python: \begin{itemize} \item \textbf{Связный список (Linked List)} --- динамическая структура, позволяющая оценить базовые механизмы управления указателями и демонстрирующая линейную сложность операций $O(n)$. \item \textbf{Хеш-таблица (Hash Table)} --- ассоциативный массив, использующий хеширование для обеспечения прямого доступа к данным. Реализация позволяет изучить методы разрешения коллизий и преимущества константной сложности $O(1)$. \item \textbf{Двоичное дерево поиска (BST)} --- иерархическая структура, обеспечивающая логарифмическую скорость доступа $O(\log n)$ и поддерживающая упорядоченность данных «из коробки». \end{itemize} \textbf{Цель работы:} Изучить внутренние алгоритмы работы перечисленных структур, реализовать их без использования встроенных высокоуровневых контейнеров и экспериментально подтвердить теоретические оценки временной сложности на случайных и отсортированных наборах данных. \section{Реализация структур данных} \subsection{Связный список} % Здесь опишите логику ll_insert, ll_find и ll_delete \subsection{Хеш-таблица} % Опишите хеш-функцию и метод цепочек \subsection{Двоичное дерево поиска} % Опишите рекурсивные алгоритмы и проблему деградации \section{Методика эксперимента} Замеры производились для наборов данных объемом $N=500, 1000, 2000, 5000, 10000$ элементов. Использовались два сценария: перемешанные (\textit{shuffled}) и отсортированные по алфавиту (\textit{sorted}) записи. Каждая операция выполнялась 5 раз с последующим вычислением среднего арифметического значения с помощью функции \texttt{time.perf\_counter()}. \section{Результаты и анализ} Было проведено 5 опытов. \subsection*{1. Бинарное дерево поиска (BST) и влияние порядка} \begin{figure}[H] \includegraphics[scale=0.7]{plots/Tree.eps} \end{figure} \begin{figure}[H] \includegraphics[scale=0.7]{plots/Tre1.eps} \end{figure} \begin{itemize} \item \textbf{Деградация на отсортированных данных:} При вставке отсортированных данных время увеличилось с \textbf{0.12с} (1000 эл.) до \textbf{13.24с} (10000 эл.). Рост более чем в 100 раз при увеличении данных в 10 раз указывает на сложность $O(n^2)$ для заполнения. Дерево выродилось в список. \item \textbf{Эффективность на перемешанных данных:} На \texttt{shuffled} данных вставка 10000 элементов заняла всего \textbf{0.03с}. Это подтверждает логарифмическую сложность $O(\log n)$ для сбалансированного дерева. \end{itemize} \subsection*{2. Хеш-таблица: Стабильность и скорость} \begin{figure}[h] \includegraphics[scale=0.7]{plots/hasht.eps} \end{figure} \begin{itemize} \item \textbf{Чувствительность к порядку:} Хеш-таблица показала идентичные результаты как на \texttt{shuffled}, так и на \texttt{sorted} данных (около \textbf{0.16с} для 10000 вставок). Это объясняется тем, что хеш-функция распределяет ключи по бакетам независимо от их исходного порядка. \item \textbf{Превосходство:} На больших объемах хеш-таблица оказалась самой быстрой структурой для поиска и удаления ($\approx 0.001$с), что подтверждает среднюю сложность $O(1)$. \item \textbf{Замечание} так как таблица содержит списки со вставкой в конец, при вставке наблюдается отклонение от линейной зависимости в сторону квадратичной \end{itemize} \subsection*{3. Связный список: Стабильная медлительность} \begin{figure}[h] \includegraphics[scale=0.7]{plots/llist.eps} \end{figure} \begin{itemize} \item \textbf{Поиск и удаление:} Связный список показал худшие результаты среди всех структур на случайных данных. Время поиска при 10000 элементах (\textbf{0.03с}) на два порядка медленнее, чем у хеш-таблицы. Это подтверждает линейную сложность $O(n)$. \item \textbf{Вставка:} Вставка в конец без указателя на хвост дает $O(n^2)$ при заполнении (\textbf{3.04с} на 10000 эл.), что сопоставимо с выродившимся деревом. \end{itemize} \subsection*{Вывод: выбор структуры данных} \begin{enumerate} \item \textbf{Хеш-таблица} — лучший выбор для реальных задач «ключ-значение». Она обеспечивает стабильное $O(1)$ и не зависит от порядка входящих данных. \item \textbf{BST} — эффективен только при условии случайного распределения данных или использовании самобалансирующихся деревьев. В противном случае велик риск деградации до скорости списка. \item \textbf{Связный список} — в данной реализации неэффективен для поиска и массовой вставки. Его стоит использовать только для специфических задач (стеки, очереди), где работа идет преимущественно с головой списка за $O(1)$. \end{enumerate} %\section{Заключение} % Ответ на вопрос о выборе структуры в реальной жизни \end{document}