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. .. raw:: html
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 :math:`log_2(N)` takich operacji. Dlatego powiemy, że ten algorytm ma *złożoność logarytmiczną*, co w *notacji wielkiego O* oznaczamy :math:`\mathcal{O}(log N)` (czyt. *o-log-en*). .. admonition:: Praca domowa :class: def 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. ``==``.