Metoda połowienia przedziału

Kolejnym omówionym algorytmem będzie metoda połowienia przedziału. Metoda ta służy do znalezienia liczby w tablicy przy założeniu, że dane wejściowe (czyli przeszukiwana tablica) są posortowane od najmniejszej do największej. W trakcie programu operujemy na trzech zmiennych, które są indeksami to tablicy, czyli numerują pewne jej komórki. k_l wskazuje na lewą komórkę przedziału (fragmentu) tablicy, k_p na prawą komórkę, zaś k_s na środkową. Jak zwykle, na początku programu musimy zainicjalizować zmienne. W tym przypadku nasz przedział k_l - k_p będzie całą tablicą, czyli do k_l wstawiamy 0 a do k_p - indeks ostatniego elementu, czyli len(tabl) - 1. Po ustaleniu tych wartości zaczynamy pętlę while. Jak widać - jest to pętla nieskończona, gdyż warunek True jest zawsze prawdą.

Co odbywa się w pętli?

Najpierw obliczamy indeks “środkowego” elementu. Użyłem cudzysłowu, gdyż dla nieparzystej różnicy k_p - k_l środek wypadnie … no własnie, gdzie?

Następnie sprawdzamy, czy znaleźliśmy to, czego szukaliśmy. Jak tak, to drukujemy wynik. Jeżeli zaś nie, to są dwie możliwości - albo x jest na prawo od pozycji k_s, albo na lewo. Zauważ, że x nie może być na pozycji k_s, bo to właśnie sprawdziliśmy. Aktualizujemy więc przedział naszych poszukiwań, odpowienio przesuwając jeden z jego końców. Następnie wracamy do początku pętli. Panel po prawej stronie, oprócz wartości wszystkich zmiennych, wyświetla również wartości niektórych wyrażeń, np tabl[k_s], co mam nadzieję pomoże przy analizowaniu tego algorytmu.

Załóżmy teraz, że elementarną operacją algorytmu jest sprawdzenie, czy tabl[k_s]==x Zastanów się teraz, ile takich operacji wykona ten program dla tablicy zawierającej N liczb?

Okazuje się, że w najgorszym (pesymistycznym) przypadku, dokonamy \(log_2(N)\) takich operacji. Dlatego powiemy, że ten algorytm ma złożoność logarytmiczną, co w notacji wielkiego O oznaczamy \(\mathcal{O}(log N)\) (czyt. o-log-en).

Praca domowa

W powyższym algorytmie jest poważny błąd: program działa w nieskończoność, jeżeli szukamy liczby, której nie ma w tablicy. Łatwo to sprawdzić - poszukaj np wartości x=4. Zobacz, co się dzieje z przebiegiem programu?

Spróbuj ułożyć taki warunek logiczny, który po wpisaniu do instrukcji while zamiast True naprawi ten problem. W warunku tym możesz użyć zmiennych zadeklarowanych w programie, czyli tabl[], k_s, k_l, k_p oraz operacji na nich, np. ==.