Wyszukiwanie binarne

Wyszukiwanie binarne
ilustracja
Rodzaj

Podstawowy algorytm wyszukiwania

Struktura danych

tablica

Złożoność
Czasowa

O ( log 2 n ) {\displaystyle O(\log _{2}n)}

Pamięciowa

O ( 1 ) {\displaystyle O(1)}

Wyszukiwanie binarne – algorytm opierający się na metodzie dziel i zwyciężaj, który w czasie logarytmicznym stwierdza, czy szukany element znajduje się w uporządkowanej tablicy i jeśli się znajduje, podaje jego indeks. Np. jeśli tablica zawiera milion elementów, wyszukiwanie binarne musi sprawdzić maksymalnie 20 elementów ( log 2 1 000 000 20 ) {\displaystyle (\log _{2}{1\,000\,000}\approx 20)} w celu znalezienia żądanej wartości. Dla porównania wyszukiwanie liniowe wymaga w najgorszym przypadku przejrzenia wszystkich elementów tablicy.

Zasada działania algorytmu

Uporządkowana tablica jest dzielona na coraz mniejsze przedziały do momentu, gdy przedział osiągnie długość jeden, kiedy możemy jednym sprawdzeniem określić, czy element znajduje się w tablicy.

W pojedynczym kroku rozważa się jeden przedział charakteryzowany dwoma indeksami: początkowym a {\displaystyle a} i końcowym b . {\displaystyle b.} Algorytm rozpoczyna wyszukiwanie od całej tablicy.

Następnie wyznaczany jest środek tego przedziału c = a + b 2 . {\displaystyle c=\left\lfloor {\frac {a+b}{2}}\right\rfloor .}

Przedział jest zawężany – dzięki uporządkowaniu danych wiadomo, że albo poszukiwany element może znajdować się w indeksach [ a ; c ] {\displaystyle [a;c]} albo za nim. Innymi słowy wybór ogranicza się do przedziału [ a , c ] , {\displaystyle [a,c],} gdy poszukiwany element jest mniejszy lub równy zapisanemu pod indeksem c , {\displaystyle c,} albo [ c + 1 , b ] {\displaystyle [c+1,b]} w przeciwnym razie.

Algorytm kończy się niepowodzeniem, jeśli przedział będzie jednoelementowy, tzn. b = a , {\displaystyle b=a,} a pod indeksem a {\displaystyle a} nie ma poszukiwanej wartości.

Implementacja

Zastosowano język TypeScript.

/**
 * Zwraca indeks poszukiwanego elementu
 * lub null jeśli dany element w tablicy nie istnieje.
 *
 * @param tablica - posortowana tablica liczb.
 * @param szukana - poszukiwana wartość.
 */
function wyszukiwanieBinarnie(tablica: number[], szukana: number): number {
    let lewo = 0;
    let prawo = tablica.length - 1;
    let przeszukiwany_indeks;
    
    while (lewo <= prawo) {
        przeszukiwany_indeks = Math.floor((lewo + prawo) / 2);
        if (tablica[przeszukiwany_indeks] < szukana) {
            lewo = przeszukiwany_indeks + 1;
        } else if (tablica[przeszukiwany_indeks] > szukana) {
            prawo = przeszukiwany_indeks - 1;
        } else {
            return przeszukiwany_indeks;
        }
    }
    
    return null;
}


Wyszukiwanie interpolacyjne

Wariant wyszukiwania binarnego, w którym punkt podziału (indeks c {\displaystyle c} ) jest wyznaczany metodą interpolacji liniowej.

Jeśli wartości kluczy na krańcach przedziału wynoszą X a {\displaystyle X_{a}} i X b {\displaystyle X_{b}} i poszukiwana wartość X a X X b , {\displaystyle X_{a}\leqslant X\leqslant X_{b},} wówczas indeks można wyznaczyć jako c = a + t ( b a ) , {\displaystyle c=\lfloor a+t\cdot (b-a)\rfloor ,} gdzie parametr t {\displaystyle t} wynika z wartości kluczy: t = X X a X b X a . {\displaystyle t={\frac {X-X_{a}}{X_{b}-X_{a}}}.}

Algorytm charakteryzuje o wiele lepsza średnia złożoność obliczeniowa niż zwykłego wyszukiwania binarnego, wynosi bowiem Θ ( log log n ) , {\displaystyle \Theta (\log \log n),} a nie O ( log n ) . {\displaystyle O(\log n).} Ta złożoność jest osiągana tylko dla danych mających rozkład jednostajny, w przypadku pesymistycznym jest jednak liniowa. Jak podaje Knuth, testy empiryczne wykazują, że podejście to dobrze sprawdza się dla bardzo dużych rozmiarów tablic, dla niewielkich nie widać wyraźnej przewagi ze względu na bardziej złożone wyliczanie indeksu c . {\displaystyle c.}

Pomysłodawcą metody był W.W. Peterson, została użyta do wyszukiwania w posortowanych plikach; została ona opracowana ok. 1957 roku.

Zobacz też

Bibliografia

  • Donald Knuth, Sztuka programowania, T. III, Sortowanie i wyszukiwanie, WNT 2002
  • W.W. Peterson. dressing for Random-Access Storage. „IBM Journal of Research and Development”. 1(4), s. 130–146, 1957. 
Encyklopedie internetowe (algorytm wyszukiwania):
  • SNL: binærsøk