\chapter{Algoritmy vyhľadávania}


\section{Algoritmy pre neusporiadané polia}

Tieto algoritmy musia postupne hľadaný prvok porovnávať s každým prvkom poľa dovtedy, kým hľadaný prvok nenájdu alebo kým nevyčerpajú všetky prvky poľa. Typickým predstaviteľom tejto skupiny je algoritmus sekvenčného vyhľadávania alebo algoritmy, ktoré majú za úlohu zistiť určitú vlastnosť jedného alebo viacerých prvkov v poli.

\subsection{Sekvenčné vyhľadávanie}

Algoritmus sekvenčného vyhľadávania je základom všetkých ostatných vyhľadávacích algoritmov. Prehľadáva všetky prvky poľa postupne od začiatku až po nájdenie hľadaného prvku alebo po prejdenie celého obsahu poľa. Na začiatku sa algoritmus nastaví na prvý prvok poľa a porovná ho s hľadaným prvkom. Ak sa nezhodujú, prejde na ďalší prvok poľa a takto postupuje až po koniec poľa alebo po nájdenie hľadaného prvku. V prípade nájdenia prvku sa algoritmus sekvenčného vyhľadávania končí. Ak sa pri hľadaní dostane až na koniec poľa, znamená to, že v poli hľadaný prvok nie je.

Povedzme, že chceme nájsť prvok s hodnotou $1$. Vstupom algoritmu je pole prvkov a hľadaný prvok. Algoritmus postupne porovnáva každý prvok poľa s hľadaným prvkom. V tabuľke \ref{sekv11} sú zobrazené ružovou neúspešné porovnania a žltou aktuálne porovnávaný prvok. Počet porovnaní závisí od dĺžky poľa.
\begin{table}[H]
\centering
\begin{tabular}{|c|c|c|c|c|c|c|c|c|c|}

\hline
Index prvku & 1\cellcolor{pink} & 2\cellcolor{pink} & 3\cellcolor{yellow} & 4 & 5 & 6 & 7 & 8 & 9 \\
\hline
Hodnota prvku & 20\cellcolor{pink} & 13\cellcolor{pink} & 15 \cellcolor{yellow}& 8 & 11 & 1 & 25 & 32 & 19 \\
\hline

\end{tabular}
\caption{Sekvenčné vyhľadávanie --- 3. iterácia}
\label{sekv11}
\end{table} 
\noindent Výstupom algoritmu je súradnica (index) hľadaného prvku v poli, ale len ak bol prvok v poli nájdený. V prípade, že sa v poli prvok nenachádza vráti algoritmus hodnotu, ktorá nemôže byť indexom žiadneho prvku v poli (napríklad -1). V tomto prípade bol hľadaný prvok nájdený na šiestej pozícii (tab. \ref{sekv12}). \cite{weblin}

\begin{table}[H]
\centering
\begin{tabular}{|c|c|c|c|c|c|c|c|c|c|}

\hline
Index prvku & 1\cellcolor{pink} & 2\cellcolor{pink} & 3\cellcolor{pink} & 4\cellcolor{pink} & 5\cellcolor{pink} & 6\cellcolor{green} & 7 & 8 & 9 \\
\hline
Hodnota prvku & 20\cellcolor{pink} & 13\cellcolor{pink} & 15 \cellcolor{pink}& 8\cellcolor{pink} & 11 \cellcolor{pink}& 1\cellcolor{green} & 25 & 32 & 19 \\
\hline

\end{tabular}
\caption{Sekvenčné vyhľadávanie --- 6. iterácia}
\label{sekv12}
\end{table}

\subsection{Sekvenčné vyhľadávanie so zarážkou}

Jednou z nevýhod klasického sekvenčného algoritmu bolo to, že pred každým porovnaním, či sa aktuálny prvok rovná hľadanému, muselo ešte urobiť porovnanie, ktoré rozhodlo o tom, či sa nachádza aktuálny index v intervale indexov prehľadávaného poľa. Tento algoritmus umiestni na koniec poľa hľadaný prvok (zarážku) a tak zabezpečí, aby bol hľadaný prvok vždy nájdený. Ak vo vstupnom poli tento prvok nebol, nájde ho na jeho konci a ukončí sa. Odpadá tak porovnanie, či sa aktuálny index nachádza v rozmedzí indexov poľa.

\subsection{Vyhľadávanie extrému}
Tento algoritmus je určený na nájdenie prvku, ktorý má v celom poli najnižšiu (resp. najvyššiu hodnotu). Pred spustením algoritmu túto hodnotu nepoznáme, ale
algoritmus nám po prehľadaní poľa túto hodnotu oznámi.


Vstupom algoritmu je pole, v ktorom chceme zistiť extrémnu hodnotu (maximum alebo minimum). Na začiatku je označený prvý prvok poľa za maximum (resp. minimum). Postupne sa prechádzajú ďalšie prvky poľa a ak sa nájde prvok väčší ako maximum (resp. menší ako minimum), je označený za nové maximum (resp. minimum) poľa. Algoritmus sa zastaví po prehľadaní všetkých prvkov poľa. Výstupom je hodnota extrému alebo jeho poloha v poli. 

\subsection{Vyhľadávanie oboch extrémov súčasne}

Vstupom algoritmu je pole, v ktorom chceme zistiť interval, v ktorom sa hodnoty nachádzajú. Na začiatku sa zoberú prvé dva prvky poľa a ten väčší je označený za maximum a menší za minimum. Ďalej algoritmus porovnáva naraz nasledujúce dva prvky v poli. Ten väčší z nich je porovnávaný s maximom a menší s minimom. Ak sa nájde nové maximum alebo minimum, hodnoty sa zaznamenajú a pokračuje sa ďalšou dvojicou prvkov. Pri prehľadávaní poľa môžu nastať dve situácie. Ak má pole párny počet prvkov, tak sa algoritmus jednoducho skončí. Ak má pole nepárny počet prvkov, tak s posledným prvkom sa musí porovnať aj maximum aj minimum. Výstupom algoritmu sú hodnoty maxima a minima. \cite{webmmp}

\section{Algoritmy pre usporiadané polia}

V nasledujúcich algoritmoch budeme predpokladať, že vstupné pole je zoradené vzostupne, teda od najmenšieho prvku po najväčší. Algoritmy môžu fungovať samozrejme aj pre opačné zoradenie, museli by sme však k tomu prispôsobiť rozhodnutia urobené na základe porovnania hľadaného prvku s aktuálnym. 

\subsection{Sekvenčné vyhľadávanie s podmienkou}

Podobne ako pri obyčajnom sekvenčnom vyhľadávaní algoritmus prehľadáva prvky poľa od jeho začiatku. V tomto prípade sa však algoritmus nekončí iba v prípade, že prejde celé pole alebo nájde hľadaný prvok, ale algoritmus sa ukončí aj v prípade, že aktuálny prvok je väčší ako hľadaný. 

Povedzme, že chceme nájsť prvok s hodnotou $13$.
Vstupom algoritmu je zoradené pole prvkov, v ktorom budeme vyhľadávať, a prvok, o ktorom chceme vedieť, či sa v poli nachádza.
V každom cykle algoritmus zisťuje, či je aktuálny prvok menší ako hľadaný.
\begin{table}[H]
\centering
\begin{tabular}{|c|c|c|c|c|c|c|c|c|c|}

\hline
Index prvku & 1\cellcolor{pink} & 2\cellcolor{pink} & 3\cellcolor{pink} & 4\cellcolor{pink} & 5\cellcolor{yellow} & 6 & 7 & 8 & 9 \\
\hline
Hodnota prvku & 2\cellcolor{pink} & 3\cellcolor{pink} & 5 \cellcolor{pink}& 8\cellcolor{pink} & 11 \cellcolor{yellow}& 12 & 15 & 20 & 21 \\
\hline

\end{tabular}
\caption{Sekvenčné vyhľadávanie s podmienkou --- 5. iterácia}
\label{sekv31}
\end{table}
\noindent Ak nie je, potom je aktuálny prvok ešte raz porovnaný s hľadaným prvkom. Ak sa tieto prvky rovnajú, hľadaný prvok sa v poli nachádza a algoritmus sa úspešne ukončí. Ak sa prvky nerovnajú, znamená to, že hľadaný prvok sa v poli nenachádza a vyhľadávanie končí. Keďže pole je zoradené a aktuálny prvok je väčší ako hľadaný, je ďalšie prehľadávanie už zbytočné. \cite{sols3s}

\begin{table}[H]
\centering
\begin{tabular}{|c|c|c|c|c|c|c|c|c|c|}

\hline
Index prvku & 1\cellcolor{pink} & 2\cellcolor{pink} & 3\cellcolor{pink} & 4\cellcolor{pink} & 5\cellcolor{pink} & 6\cellcolor{pink} & 7\cellcolor{red} & 8 & 9 \\
\hline
Hodnota prvku & 2\cellcolor{pink} & 3\cellcolor{pink} & 5 \cellcolor{pink}& 8\cellcolor{pink} & 11\cellcolor{pink} & 12\cellcolor{pink} & 15\cellcolor{red} & 20 & 21 \\
\hline

\end{tabular}
\caption{Sekvenčné vyhľadávanie s podmienkou --- 7. iterácia}
\label{sekv32}
\end{table}

\subsection{Binárne vyhľadávanie}

V usporiadanom poli sa prakticky nepoužíva sekvenčné vyhľadavanie kvôli jeho veľkej časovej náročnosti. Z časových dôvodov je veľmi nevýhodné porovnávať postupne všetky prvky v poli až po nájdenie toho, ktorý hľadáme alebo zistenie, že sa prvok v poli nenachádza. Výhodou zotriedeného poľa je, že môžeme použiť pri hľadaní hodnoty metódu polenia intervalu. Na tejto metóde je založený algoritmus binárneho vyhľadávania. S každou iteráciou sa prehľadávaný interval zmenší na polovicu.
% Požíva sa algoritmus binárneho vyhľadávania, ktorý spočíva v polení intervalu --- s každou iteráciou sa zmenší počet prvkov na polovicou. Pre akékoľvek pole má  


Povedzme, že hľadáme napríklad číslo $20$. Vstupom algoritmu je zoradené pole prvkov, v ktorom budeme vyhľadávať, a prvok, o ktorom chceme vedieť, či sa v poli nachádza a ak áno, tak na akej pozícii. V cykle sa vyberie stred poľa (tab. \ref{bin1}) a podľa toho, či je hľadaný prvok väčší alebo menší ako zvolený stred, sa vyradí jedna alebo druhá polovica poľa. V tomto prípade sa vyradí ľavá polovica poľa (ružová časť v tab. \ref{bin1}) vrátane stredu.
\begin{table}[H]
\centering
\begin{tabular}{|c|c|c|c|c|c|c|c|c|c|}

\hline
Index prvku & 1\cellcolor{pink} & 2\cellcolor{pink} & 3\cellcolor{pink} & 4\cellcolor{pink} & 5\cellcolor{yellow} & 6 & 7 & 8 & 9 \\
\hline
Hodnota prvku & 2\cellcolor{pink} & 3\cellcolor{pink} & 5 \cellcolor{pink}& 8\cellcolor{pink} & 11 \cellcolor{yellow}& 12 & 15 & 20 & 21 \\
\hline

\end{tabular}
\caption{Binárne vyhľadávanie --- 1. iterácia}
\label{bin1}
\end{table}

\noindent Ak je hľadaným prvokom práve vybraný stred, tak sa algoritmus úspešne ukončí. V prípade, že stred nie je hľadaným prvkom, tak sa cyklus opakuje až dovtedy, kým stred nebude hľadaným prvkom alebo sa skončí, ak sa prvok v poli nenachádza. Pri úspešnom konci algoritmus vráti pozíciu prvku v poli, pri neúspešnom vráti hodnotu ktorá nemôže byť indexom žiadneho prvku. V tomto prípade algoritmus skončí s výstupom 8 (v tab. \ref{bin2} zelený prvok), pretože na tej pozícii sa našiel hľadaný prvok. \cite{solbis, webbin, webbi2}

\begin{table}[H]
\centering
\begin{tabular}{|c|c|c|c|c|}

\hline
Index prvku & 6 & 7 & 8\cellcolor{green} & 9 \\
\hline
Hodnota prvku & 12 & 15 & 20\cellcolor{green} & 21 \\
\hline

\end{tabular}
\caption{Binárne vyhľadávanie --- 2. iterácia}
\label{bin2}
\end{table}

%\paragraph{Príklad vyhľadávania:}
 %Vo vstupnom poli sa vyberie prvok v strede tak ako je zobrazené v tabuľke \ref{bin1}.


\subsection{Interpolačné vyhľadávanie}

V reálnom živote sa nepoužíva binárny spôsob vyhľadávania, ale skôr sa interpoluje --- napr. slovník sa snažíme otvoriť približne v mieste, kde predpokladáme výskyt hľadaného slova. Predpokladom tohto spôsobu vyhľadávania je rovnomerné rozloženie údajov v prehľadávanej dátovej štruktúre. Ak údaje nie sú rovnomerne rozložené je výhodnejšie použiť binárne vyhľadávanie.

Povedzme, že hľadáme napríklad číslo $12$. Vstupom algoritmu je zoradené pole prvkov, v ktorom budeme vyhľadávať, a prvok, o ktorom chceme vedieť, či sa v poli nachádza.
%Rovnako ako pri binárnom vyhľadávaní sa na začiatku zistí, či sa hľadaný prvok môže nachádzať v poli. 
Na začiatku sa vypočíta podľa vzorca predpokladaná pozícia hľadaného prvku (tab. \ref{int1} žltý prvok). Ak sa hľadaný prvok nenachádza na vypočítanej pozícii, tak sa postupuje ako pri binárnom vyhľadávaní --- vyradí sa jedna alebo druhá časť poľa vrátane vypočítanej pozície (ružová časť v tab \ref{int1}). 
\begin{table}[H]
\centering
\begin{tabular}{|c|c|c|c|c|c|c|c|c|c|}

\hline
Index prvku & 1\cellcolor{pink} & 2\cellcolor{pink} & 3\cellcolor{pink} & 4\cellcolor{pink} & 5\cellcolor{yellow} & 6 & 7 & 8 & 9 \\
\hline
Hodnota prvku & 2\cellcolor{pink} & 3\cellcolor{pink} & 5 \cellcolor{pink}& 8\cellcolor{pink} & 11 \cellcolor{yellow}& 12 & 15 & 20 & 21 \\
\hline

\end{tabular}
\caption{Interpolačné vyhľadávanie --- 1. iterácia}
\label{int1}
\end{table}
\noindent Cyklus sa opakuje až pokým sa na vypočítanej pozícii nenachádza hľadaný prvok prípadne sa hľadanie skončí, ak sa zistí, že sa prvok v poli už nemôže nachádzať. Výstupom je index hľadaného prvku alebo v prípade neúspechu číslo, ktoré nemôže byť indexom žiadneho prvku v poli. V tomto prípade bol prvok nájdený na šiestej pozícii (tab. \ref{int2} zelený prvok). \cite{webint, webin2}
\begin{table}[H]
\centering
\begin{tabular}{|c|c|c|c|c|c|}

\hline
Index prvku  & 6\cellcolor{green} & 7 & 8 & 9 \\
\hline
Hodnota prvku  & 12\cellcolor{green} & 15 & 20 & 21 \\
\hline

\end{tabular}
\caption{Interpolačné vyhľadávanie --- 2. iterácia}
\label{int2}
\end{table}

