160 likes | 317 Views
Vyhledávání. Principy vyhledávání Klasifikace klíče: Interní klíč – je součástí prohlížených záznamů Externí klíč – není jeho součástí, je jím např. index prvku v poli, pořadí záznamu v souboru apod. Primární klíč – jednoznačně identifikuje záznam (např. rodné číslo)
E N D
Vyhledávání Principy vyhledávání • Klasifikace klíče: • Interní klíč – je součástí prohlížených záznamů • Externí klíč –není jeho součástí, je jím např. index prvku v poli, pořadí záznamu v souboru apod. • Primární klíč – jednoznačně identifikuje záznam (např. rodné číslo) • Sekundární klíč – není jedinečný (např. jméno)
Metody vyhledávání Sekvenční vyhledávání v prostém seznamu Sekvenční vyhledávání v seřazeném seznamu Binární vyhledávání Index-sekvenční vyhledávání Vyhledávání ve stromě (ve vyhledávacím stromě) Vyhledávání v seznamech s rozptýlenými záznamy (v hešovacích tabulkách)
Adresní vyhledávání Založeno na znalosti vztahu mezi hodnotami klíče a umístěním prvku v datové struktuře Použití Množina přípustných klíčů není rozsáhlá Množina přípustných klíčů je zobrazitelná na množinu adres prvků
Příklady použití: práce s celočíselnými hodnotami v interval např. 0..255 Příklad: Seřaďte vzestupně údaje o výšce měřeného vzorku obyvatelstva a uveďte četnost výskytu jednotlivých hodnot (po centimetrech). Řešíme problematiku Seřazení Vyhledávání Vložení Odstranění Dále viz Vyhledávání v rozptýlených tabulkách
Sekvenční (lineární)vyhledávání const N=10; type COSI= string[10] {popř. něco jiného} T=array[1..N] of COSI; function HLEDEJ(A:T; B:COSI):byte; {0..N} var I:byte; begin HLEDEJ:=0; for I:=1 to N do if A[I]=Bthen HLEDEJ:=I end
popř. příkazovou část funkce HLEDEJ řešíme optimálněji begin HLEDEJ:=0; I:=0; repeat I:=I+1; if A[I]=Bthen HLEDEJ:=I until (I=N) or (A[I]=B) end
Je-li seznam A setříděn, pak k případnému nalezení hodnoty KLIC vede upravený algoritmus (zbytečné prohlížet složky seznamu A s větší hodnotou, než je hodnota KLIC): begin HLEDEJ:=0; I:=0; repeat I:=I+1; if A[I]=Bthen HLEDEJ:=I until (I=N) or (A[I]>=B) end
Binární vyhledávání Pro setříděný seznam A (tabulku, soubor atd.) je velmi efektivní vyhledávací metodou. function HLEDEJ(A:T; B:COSI) : byte; {0..N} var FI, LI, I : byte; begin HLEDEJ:=0; FI:=1; LI:=1; repeat I:=(FI+LI) div 2; if A[I]>B then LI:=I-1 else FI:=I+1 until (B=A[I]) or (FI>LI); if B=A[I] then HLEDEJ:=I end
Dijkstrova metoda binárního vyhledávání vychází z předpokladu, že seznamA může obsahovat více záznamů s hodnotou KLIC. Nalezen je prv-ní záznam s hodnotou KLIC: begin HLEDEJ:=0; FI:=0; LI:=N; while LI<>(FI+1) do begin I:=(FI+LI) div 2; if A[I]<=Bthen FI:=I else LI:=I end; if A[I]=Bthen HLEDEJ:=I end
Metoda binárního vyhledávání je řešitelná rovněž rekurzívním algoritmem, i když méně efektivním: Function BV(A:T;X:COSI;FI,LI:byte) : byte; var I : byte; begin if FI>LI then BV:=0 else begin I:=(FI+LI) div 2; if A[I]=B then BV:=I elseif B<A[I] then BV:=BV(A,B,FI,I-1) else BV:=BV(A,B,I+1,LI) end end
Index-sekvenční vyhledávání Pro setříděný seznam (tabulku, soubor atd.) tvoříme zpravidla tabulku nazvanou index, která obsahuje vedle klíče i ukazatel na odpovídající záznam v původním seznamu. Pro rozsáhlé soubory je efektivní využít víceúrovňové indexování; vedle primárního indexu ukazujícího do sekvenčního souboru využíváme jednoho (či více) klíčů sekundárních sloužícího jako index indexu primárního.
Vyhledávání v rozptýlených tabulkách Tabulka s přímým přístupem je z hlediska časové složitosti vyhledávání (přístupu) nejefektivnější metodou. Nevýhodou je její paměťová náročnost; pro rozsáhlé množiny přípustných hodnot klíčů (např. příjmení) je nepoužitelná. Pozornost je věnována metodám implementace tabulek založených na zobrazení klíčů do množiny adres. Zobrazení klíčů však není jednoznačné, hovoříme o tzv. hašování (hashing, rozptýlení).
Zobrazení (transformace) klíče na adresu není vzájemně jednoznačná existují dva či více klíčů se stejnou adresou; řešíme tzv. kolize existuje adresa, které neodpovídá žádný klíč; Běžná, optimální popř. špatná struktura rozmístění klíčů v hašovací tabulce je důsledkem špatně volené hašovací funkce
Hašovací funkce m = h(k) jako generátor rovnoměrně rozložených adresm generovaných z klíčů k klíč k K* adresa m {M} Elementární hašovací funkce: m = h(k) = k mod m’ kde m’ je nejmenší prvočíslo > mmax
Příklady na hašovací funkci: jsou-li např. klíčem hmotnosti skupiny lidí s přesností na 0.5 kg; přičemž k<1,125>, pak hašovací funkce může mít tvar např. m = 2 * k jsou-li klíčem např. jména (řetězce znaků), pak hašovací funkce může být řešena algoritmem např. m:=0; for I:=1 to length(S) do m:=m+(ord(UpCase(S[I]))-65; m:=m mod 11; ‘Albert’ (0+11+1+4+17+19) = 52 mod 11 8
Řešení kolizí kolize nastává, jsou-li 2 či více klíčů hašovány na jednu adresu buď hledáme perfektní hašování (je obtížné) nebo se smíříme se sekvenčním prohledáváním kolizního prostoru – kapsy Perfektní hašování, otevřené hašování dvoustupňové hašování v 1. kroku je např. h(k) = k mod 11 při kolizi 2. stupeň hašování, např. h(k)=(k mod 5) +1 je krokem hledání další pozice vpravo