2026-rff_mp/ProninVV/aufgabe-1-data-structures/report/document.tex

137 lines
11 KiB
TeX
Raw Normal View History

\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{Результаты и анализ}
2026-03-24 18:12:09 +00:00
Было проведено серию опытов для $N$ от 500 до 10000.
2026-03-21 18:22:39 +00:00
\subsection*{1. Бинарное дерево поиска (BST) и влияние порядка}
\begin{figure}[H]
2026-03-24 18:12:09 +00:00
\centering
\includegraphics[scale=0.7]{plots/TTree1.eps}
\caption{Зависимость времени выполнения операций в BST от объема данных}
2026-03-21 18:22:39 +00:00
\end{figure}
\begin{figure}[H]
2026-03-24 18:12:09 +00:00
\centering
\includegraphics[scale=0.7]{plots/TTree2.eps}
2026-03-21 18:22:39 +00:00
\end{figure}
\begin{itemize}
2026-03-24 18:12:09 +00:00
\item \textbf{Деградация на отсортированных данных:} При вставке отсортированных данных время увеличилось с \textbf{0.124с} ($N=1000$) до \textbf{13.27с} ($N=10000$). Рост времени в 100 раз при увеличении объема данных в 10 раз четко указывает на квадратичную сложность $O(n^2)$ для процесса заполнения всей структуры. Дерево выродилось в линейный список, и поиск места вставки стал занимать $O(n)$ вместо ожидаемого $O(\log n)$.
\item \textbf{Эффективность на перемешанных данных:} На \texttt{shuffled} данных вставка 10000 элементов заняла всего \textbf{0.031с}. Это подтверждает логарифмическую сложность $O(\log n)$ для операций в дереве при случайном распределении ключей.
2026-03-21 18:22:39 +00:00
\end{itemize}
\subsection*{2. Хеш-таблица: Стабильность и скорость}
2026-03-24 18:12:09 +00:00
\begin{figure}[H]
\centering
\includegraphics[scale=0.7]{plots/Thasht1.eps}
\end{figure}
\begin{figure}[H]
\centering
\includegraphics[scale=0.7]{plots/Thasht2.eps}
2026-03-21 18:22:39 +00:00
\end{figure}
\begin{itemize}
2026-03-24 18:12:09 +00:00
\item \textbf{Чувствительность к порядку:} Хеш-таблица показала идентичные результаты как на \texttt{shuffled}, так и на \texttt{sorted} данных (около \textbf{0.165с} -- \textbf{0.167с} для 10000 вставок). Это объясняется тем, что хеш-функция распределяет ключи по бакетам независимо от их исходного порядка, предотвращая деградацию структуры.
\item \textbf{Превосходство:} На больших объемах хеш-таблица оказалась самой быстрой структурой для поиска и удаления ($\approx 0.001$с при $N=10000$), что подтверждает теоретическую среднюю сложность $O(1)$.
\item \textbf{Замечание:} Так как реализация использует списки для разрешения коллизий со вставкой в конец, при заполнении таблицы наблюдается рост времени вставки, стремящийся к квадратичному, однако абсолютные значения остаются на порядки ниже, чем у выродившегося BST.
2026-03-21 18:22:39 +00:00
\end{itemize}
2026-03-24 18:12:09 +00:00
\subsection*{3. Связный список: Линейная зависимость}
\begin{figure}[H]
\centering
\includegraphics[scale=0.7]{plots/Tlinklist1.eps}
\end{figure}
2026-03-21 18:22:39 +00:00
2026-03-24 18:12:09 +00:00
\begin{figure}[H]
\centering
\includegraphics[scale=0.7]{plots/Tlinklist2.eps}
2026-03-21 18:22:39 +00:00
\end{figure}
\begin{itemize}
2026-03-24 18:12:09 +00:00
\item \textbf{Поиск и удаление:} Связный список показал худшие результаты среди всех структур на случайных данных. Время поиска при 10000 элементах (\textbf{0.029с}) значительно медленнее, чем у BST на перемешанных данных (\textbf{0.0002с}). Это подтверждает линейную сложность $O(n)$.
\item \textbf{Вставка:} Вставка (вероятно, в конец или с сохранением порядка) дает $O(n^2)$ при заполнении (\textbf{2.83с} -- \textbf{3.00с} на 10000 эл.). Характер роста времени при переходе от $N=5000$ (\textbf{0.71с}) к $N=10000$ подтверждает квадратичную зависимость.
2026-03-21 18:22:39 +00:00
\end{itemize}
\subsection*{Вывод: выбор структуры данных}
\begin{enumerate}
2026-03-24 18:12:09 +00:00
\item \textbf{Хеш-таблица} — наиболее универсальный выбор. Она обеспечивает стабильное $O(1)$ для поиска и не зависит от порядка входящих данных.
\item \textbf{BST} — крайне эффективен ($O(\log n)$) при случайном распределении данных, но без механизмов самобалансировки критически уязвим к отсортированным входным последовательностям, замедляясь до уровня списка.
\item \textbf{Связный список} — продемонстрировал самую низкую производительность на операциях поиска и массовой вставки. Его использование оправдано только в специфических сценариях (например, реализация стека), где работа ведется исключительно с головой списка за $O(1)$.
2026-03-21 18:22:39 +00:00
\end{enumerate}
2026-03-24 18:12:09 +00:00
2026-03-21 18:22:39 +00:00
2026-03-24 18:12:09 +00:00
\subsection*{Сводная таблица результатов}
\begin{table}[H]
\centering
\small
\begin{tabular}{|l|l|c|c|c|c|c|}
\hline
\textbf{Структура} & \textbf{Режим} & \textbf{Опер.} & \textbf{N=500} & \textbf{N=1000} & \textbf{N=5000} & \textbf{N=10000} \\ \hline
\multirow{3}{*}{LinkList} & Shuffled & Insert & 0.0066 & 0.0292 & 0.7089 & 2.8358 \\
& Shuffled & Find & 0.0012 & 0.0026 & 0.0147 & 0.0289 \\
& Sorted & Insert & 0.0065 & 0.0290 & 0.7637 & 3.0042 \\ \hline
\multirow{3}{*}{HashTable} & Shuffled & Insert & 0.0007 & 0.0022 & 0.0468 & 0.1670 \\
& Shuffled & Find & 0.0001 & 0.0002 & 0.0008 & 0.0014 \\
& Sorted & Insert & 0.0007 & 0.0022 & 0.0448 & 0.1646 \\ \hline
\multirow{3}{*}{BinTree} & Shuffled & Insert & 0.0009 & 0.0021 & 0.0145 & 0.0309 \\
& Shuffled & Find & 0.0001 & 0.0001 & 0.0002 & 0.0002 \\
& Sorted & Insert & \textbf{0.0298} & \textbf{0.1239} & \textbf{3.3052} & \textbf{13.2706} \\ \hline
\end{tabular}
\caption{Сравнение минимального времени выполнения операций (в секундах) в зависимости от объема данных $N$}
\end{table}
2026-03-21 17:53:41 +00:00
2026-03-24 18:12:09 +00:00
\end{document}