Binárne vyhľadávanie: Rozdiel medzi revíziami

z Wikipédie, slobodnej encyklopédie
Smazaný obsah Přidaný obsah
Zemiak123 (diskusia | príspevky)
→‎Implementácie: zmena v kóde - vyhľadávanie teraz vracia index hľadaného elementu, čo je obvyklejšie
Značky: úprava z mobilu úprava z mobilného webu
Zemiak123 (diskusia | príspevky)
→‎Implementácie: implementacia 2 teraz vracia index hľadanej hodnoty
Značky: úprava z mobilu úprava z mobilného webu
Riadok 6: Riadok 6:


== Implementácie ==
== Implementácie ==

Rekurzívna implementácia binárneho vyhľadávania v jazyku [[Python]] 3:
Rekurzívna implementácia binárneho vyhľadávania v jazyku [[Python]] 3:
<source lang="python">
<source lang="python">
def binarySearch(zoznam, hodnota, vlavo, vpravo):
def binarySearch(zoznam, hodnota, vlavo, vpravo):
if vlavo > vpravo:
if vlavo > vpravo:
return -1 # hodnota nenajdená
return -1 # hodnota nenajdena

stred = vlavo + int((vpravo - vlavo) / 2)
stred = vlavo + int((vpravo - vlavo) / 2)
if zoznam[stred] == hodnota:
return stred
if hodnota < zoznam[stred]:
if hodnota < zoznam[stred]:
Riadok 22: Riadok 17:
else:
else:
return binarySearch(zoznam, hodnota, stred + 1, vpravo)
return binarySearch(zoznam, hodnota, stred + 1, vpravo)
</source>
if zoznam[stred] == hodnota:
return stred
</source>


Vďaka tomu, že rekurzívne volania sú na konci funkcie ([[koncová rekurzia]]), je možné túto implementáciu prepísať len pomocou cyklu
Vďaka tomu, že rekurzívne volania sú na konci funkcie ([[koncová rekurzia]]), je možné túto implementáciu prepísať len pomocou cyklu
<source lang="python">
<source lang="python">
def binarySearch(zoznam, hodnota, vlavo, vpravo):
def binarySearch(zoznam, hodnota, vlavo, vpravo):
while vlavo <= vpravo:
while vlavo <= vpravo:
stred = vlavo + int((vpravo - vlavo) / 2)
stred = vlavo + int((vpravo - vlavo) / 2)

if zoznam[stred] == hodnota:
return True
if hodnota < zoznam[stred]:
if hodnota < zoznam[stred]:
vpravo = stred - 1
vpravo = stred - 1
else:
else:
vlavo = stred + 1

vlavo = stred + 1
if zoznam[stred] == hodnota:
return False
return stred

return -1 # hodnota nenajdena
</source>
</source>



Verzia z 11:10, 15. august 2021

Binárne vyhľadávanie je vyhľadávací algormitmus na nájdenie zadanej hodnoty v usporiadanom zozname pomocou skracovania zoznamu o polovicu v každom kroku. Binárne vyhľadávanie nájde medián, urobí porovnanie a na základe tohoto sa rozhodne o pokračovaní v hornej alebo dolnej časti zoznamu a rekurzívne sa pokračuje od začiatku.

Binárne vyhľadávanie je algoritmus s logaritmickou zložitosťou O(log n). Presnejšie, iterácií je potrebných na získanie výsledku. Je značne rýchlejšie ako lineárne vyhľadávanie, ktoré má zložitosť O(n). Dá sa vyjadriť rekurzívne aj iteratívne, avšak vo veľa programovacích jazykoch je rekurzívny zápis oveľa elegantnejší.

Binárne vyhľadávanie je príkladom algoritmu typu rozdeľ a panuj.

Implementácie

Rekurzívna implementácia binárneho vyhľadávania v jazyku Python 3:

def binarySearch(zoznam, hodnota, vlavo, vpravo):
    if vlavo > vpravo:
        return -1     # hodnota nenajdena
    stred = vlavo + int((vpravo - vlavo) / 2)
        
    if hodnota < zoznam[stred]:
        return binarySearch(zoznam, hodnota, vlavo, stred - 1)
    else:
        return binarySearch(zoznam, hodnota, stred + 1, vpravo)
    
    if zoznam[stred] == hodnota:
        return stred

Vďaka tomu, že rekurzívne volania sú na konci funkcie (koncová rekurzia), je možné túto implementáciu prepísať len pomocou cyklu

def binarySearch(zoznam, hodnota, vlavo, vpravo):
    while vlavo <= vpravo:
        stred = vlavo + int((vpravo - vlavo) / 2)

        if hodnota < zoznam[stred]:
            vpravo = stred - 1
        else:
            vlavo  = stred + 1

        if zoznam[stred] == hodnota:
            return stred

    return -1      # hodnota nenajdena

Implementačné komplikácie

Keď Jon Bentley priradil binárne vyhľadávanie ako problém pre kurz profesionálnych programátorov, zistil, že 90% z nich nedokáže poskytnúť správne riešenie. Ďalšia štúdia publikovaná v roku 1988 ukazuje, že správny kód pre binárne vyhľadávanie sa dá nájsť len v 5 z 20 učebniciach.

Bentley-ho vlastná implementácia binárneho vyhľadávania, publikovaná v roku 1986 v knihe Programming Pearls, obsahovala chybu ktorá pri vysokých číslach zbytočne spôsobovala prekročenie maximálnej veľkosti premennej typu integer. Chyba nebola odhalená viac ako 20 rokov.[1] V oficiálnej knižnici jazyka Java sa vyskytovala rovnaká chyba po dobu viac než 9 rokov.[2] Ukážkový kód algoritmu, ktorý bol na tejto stránke, pred úpravou túto chybu obsahoval tiež.

Referencie

  1. https://research.googleblog.com/2006/06/extra-extra-read-all-about-it-nearly.html
  2. http://bugs.java.com/bugdatabase/view_bug.do?bug_id=5045582