Binární vyhledávací strom J e d n á s e o o d rů d u o b e c ně j š í d a t o v é s t r u k t u r y z v a n é s t r o m. P o j e m p o c h á z í z t e o r i e g r a f ů, k d e j e s t r o m e m n a z ý v á n s o u v i s l ý g r a f b e z c y k l ů. S k l á d á s e z u z l ů a h r a n. V p r o g r a m o v é r e p r e z e n t a c i j s o u u z l y z á z n a m y a n e s o u j e d n a k i n f o r m a c i, j e d n a k o d k a z y n a d a l š í u z l y. H r a n y j s o u r e p r e z e n t o v á n y u k a z a t e l i a u rč u j í v a z b y m e z i j e d n o t l i v ý m i u z l y. S t r o m y č a s t o b ý v a j í z o b r a z o v á n y g r a f i c k y: P o j í s e s n i m i c e l á ř a d a t e r m í n ů. P o k u s í m s e j e v e s t r uč n o s t i s h r n o u t. U z e l z c e l a n a h oř e, k t e r ý m s e v s t u p u j e d o c e l é h o s t r o m u, s e n a z ý v á k oř e n. U z l y, k e k t e r ý m v e d o u h r a n y z ně k t e r é h o u z l u, j s o u o z n ač o v á n y z a s y n y t o h o t o u z l u. K až d ý s y n m ůž e m í t s v é s y n y a ti z a s e s v é a t d. S y n s e v š í m s v ý m p o t o m s t v e m t v oř í j e d e n z p o d s t r o m ů o t c o v s k é h o u z l u. L i s t y j s o u p a k u z l y b e z s y n ů; ji m i s t r o m k o nč í. Če t n o s t s t r o m u j e m a x i m á l n í p oč e t s y n ů, k t e r é m á ně k t e r ý z j e h o u z l ů. C e s t a o d k oř e n e k ně k t e r é m u z u z l ů s e n a z ý v á vě t e v. V z h l e d e m k t o m u, ž e s t r o m y n e o b s a h u j í c y k l y, j e vět e v vž d y j e d n o z n ač n ě u rč e n a. A k o n eč n ě h l o u b k a s t r o m u j e d é l k a (p oč e t h r a n) m a x i m á l n í vět v e. U d á v á, j a k á j e n e j vět š í v z d á l e n o s t m e z i k oř e n e m a ně k t e r ý m z li s t ů. Proč binární? B i n á r n í: Č e t n o s t s t r o m u j e d v ě. K až d ý j e h o u z e l s m í m í t n a n e j v ý š d v a s y n y. P o už í v a j í s e p r o n ě u k a z a t e l e L e v ý a P r a v ý. Vyhledávání T e n t o d r u h s t r o m u j e o r g a n i z o v á n p r o s n a d n é v y h l e d á v á n í j e d n o t l i v ý c h p r v k ů. Č á s t n e s e n é i n f o r m a c e t v oř í k l í č. K l íč e v l e v é m p o d s t r o m u k až d é h o u z l u j s o u vž d y m e n š í n e ž k l í č u z l u, k l íč e v p r a v é m p o d s t r o m u j s o u n a o p a k vět š í. D í k y t o m u j e v y h l e d á v á n í u rčit é h o d n o t y k l íč e s n a d n é. J e-li m e n š í, n e ž k l í č z k o u m a n é h o u z l u, m u s í s e p o k r oč it k l e v é m u s y n o v i. J e-li vě t š í, b u d e h l e d á n í p o k r ač o v a t v p r a v o.
P r a v i d l o m e n š í v l e v o, vět š í v p r a v o j e p o mě r n ě v o l n é a u z l y l z e v e s t r o m u u s p oř á d a t m n o h a z pů s o b y, a n i ž b y d o š l o k j e h o p o r u š e n í. O v š e m p r a v i d lů m t a k é v y h o v í z c e l a d e g e n e r o v a n ý s t r o m, j e h o ž k oř e n p o n e s e k l í č 2, v š e c h n y u z l y b u d o u m í t p r á z d n ý l e v ý p o d s t r o m a j e ji c h p r a v ý m s y n e m b u d e n e j b l iž š í h o d n o t a. T a k o v ý s t r o m v p o d s t a t ě př e š e l d o li n e á r n í h o s e z n a m u, n i c m é n ě s p lň u j e v e š k e r é n á r o k y n a b i n á r n í v y h l e d á v a c í s t r o m. Praxe: Ze všeho nejdříve se podíváme na deklarace, jejichž pomocí budeme strom realizovat: type strom=array [1..100] of Integer; var st:strom; počet, cis:integer; ^tato část kódu nám říká, že strom budeme vytvářet pomocí pole, a zadeklamovali jsme si základní proměnné, které budeme později používat nyní rekurzivní procedura pro vytvoření samotného binárního vyhledávacího stromu: procedure VytvorBVS(i,x:integer; var s:strom); if s[1]=0 then s[1]:=x; pocet:=1; s[2]:=0; s[3]:=0; if x<s[i] then if s[2*i]=0 then s[2*i]:=x VytvorBVS((2*i),x,s); if x>s[i] then if s[((2*i)+1)]=0 then s[((2*i)+1)]:=x VytvorBVS(((2*i)+1),x,s); procedura pro vytvoření hlady: procedure halda; var i:integer; for i:=1 to 100 do st[i]:=0; halda se musí vytvořit ihned se startem programu, to uděláme tak že jí vložíme do procedury samotného Formuláře: procedure TForm1.FormCreate(Ser: TObject); halda; procedura pro vytvoření stromu ze souboru s čísly:
procedure TForm1.Button2Click(Ser: TObject); var f: TextFile; a: Integer; AssignFile(f, 'File1.txt'); reset(f); while not EOF(f) do readln(f, a); VytvorBVS(1,a, St); CloseFile(f); procedura pro výpis do mema: procedure tisk (i,h:integer); var s1:string; j:integer; if st[i]<>0 then tisk(2*i+1,h+1); s1:=''; for j:=1 to h do s1:=s1+' s1:=s1+inttostr(st[i]); memo1.lines.add(s1); tisk(2*i,h+1); memo1.lines.clear; tisk(1,1); '; přehlednější než výpis je však grafické vykreslení do komponenty image, to uděláme následovně: procedure TForm1.Button3Click(Ser: TObject); procedure vykresli(i, x, y, sirka: Integer); sirka:=sirka div 2; if st[2*i]<>0 then image1.canvas.moveto(x,y); image1.canvas.lineto(x-sirka,y+30); vykresli(2*i,x-sirka,y+30, sirka) if St[2*i+1]<>0 then image1.canvas.moveto(x,y); image1.canvas.lineto(x+sirka,y+30); vykresli(2*i+1,x+sirka,y+30,sirka)
Image1.Canvas.TextOut(x-5, y-8, IntToStr(St[i])); image1.canvas.brush.color:=clwhite; image1.canvas.brush.style:=bssolid; image1.canvas.rectangle(0,0,image1.width,image1.height); vykresli(1, image1.width div 2, 10, image1.width div 2,); ^zde by bylo možná lepší proceduru lépe popsat, jelikož je dosti dlouhá: Procedura pro vykreslení je součásti procedury buttonu3, na který když klikneme tak se nám strom vykreslí, zadali jsme si několik proměnných i pro číslo, x, y a šířku výpočet pro souřadnic. Nejprve zjistíme, zdali strom není prázdný, pokud ne tak začneme vykreslovat jeho levou stranu. Příkaz MoveTo je pro přesouvání kreslícího pera na pozici x a y, a LineTo nám kreslí spojnici (větev). Totéž uděláme pro pravou stranu. Nakonec příkazem TextOut vypíšeme ke každé větvi její číslo, nebo chcete-li její hodnotu. To je celá procedura na vykreslení. V proceduře samotného buttonku pak pouze smažeme plátno, nastavíme vlastnosti kreslicího pera a zavoláme proceduru vykresli.
Čtvrtou a poslední částí programu je vyhledávání námi zadaného čísla: samotná vyhledávací procedura: procedure vyhledej (x,i:integer; s:strom;var a:integer); if x=s[i]then a:=i; if (x>s[i]) and (s[(2*i)+1]<>0) then vyhledej (x,((2*i)+1),s,a) if (x<s[i]) and (s[(2*i)]<>0) then vyhledej (x,(2*i),s,a) a:=0; button pro button: procedure TForm1.Button4Click(Ser: TObject); var cis: integer; vyhledej(strtoint(edit1.text),1,st,cis); if cis<>0 then memo1.lines.add(' '); memo1.lines.add('číslo nalezeno na řádku:'+(inttostr(cis))); memo1.lines.add('číslo nebylo nalezeno');