Upload
cormac
View
57
Download
0
Embed Size (px)
DESCRIPTION
Objektovo - Orientované Programovanie. Binárne vyhľadávacie stromy. Reprezentácia stromov ako v halde - v jednorozmernom poli: každý prvok reprezentuje jeden vrchol stromu: prvý prvok je koreň í-ty vrchol má synov na indexoch 2*i a 2*i+1 - PowerPoint PPT Presentation
Citation preview
Objektovo - Orientované Programovanie
Binárne vyhľadávacie stromy
Reprezentácia stromov ako v halde - v jednorozmernom poli:
každý prvok reprezentuje jeden vrchol stromu:
prvý prvok je koreň
í-ty vrchol má synov na indexoch 2*i a 2*i+1
treba evidovať "diery" - miesta, ktoré nereprezentujú vrcholy
pole vrcholov, kde vrchol obsahuje info a indexy do poľa pre ľavého a pravého syna pole vrcholov - každý vrchol má spájaný zoznam synov (táto reprezentácia by sa dala použiť aj na všeobecný strom)
Dynamická štruktúra pre binárny strom
type TStrom = class
info:prvok;
l,p:TStrom;
constructor Create(i:prvok; nl,np:TStrom);
function text:string; virtual;
end;
constructor TStrom.Create(i:prvok; nl, np: TStrom);
begin info:=i; l:=nl; p:=np; end;
function TStrom.text:string;
begin Result:=IntToStr(info);
end;
var s:TStrom;
... s:=nil; // prázdny strom s:=TStrom.Create(1,nil,nil); s:=TStrom.Create(1,TStrom.Create(2,nil,nil),TStrom.Create(3,nil,nil));
Základné algoritmy
na navštívenie postupne všetkých vrcholov (napr. výpis hodnôt)
pre N vrcholový binárny strom N! možných prechodov, len niektoré z nich sú rozumné => 3 algoritmy prechádzania vrcholmi stromov:
Preorder - najprv informáciu vo vrchole, potom v ľavom podstrome a na záver v pravom
Inorder - najprv spracuje ľavý podstrom, potom info vo vrchole a na záver v pravom podstrome
Postorder - najprv spracuje ľavý, potom pravý podstrom a na záver info v samotnom vrchole
naprogramujeme metódy preorder, inorder, postorder - tieto postupne spracujú všetky vrcholy podľa špecifického poradia
nasledujúce metódy vypíšu všetky vrcholy (do Memo1) v rôznych poradiach podľa príslušných algoritmov:
procedure TStrom.vypis;
// vypíše len jeden vrchol = koreňbegin Form1.Memo1.Lines.Add(text); end;
procedure TStrom.preorder;
begin
vypis; if l<>nil then l.preorder;
if p<>nil then p.preorder;
end;
procedure TStrom.inorder;
begin if l<>nil then l.inorder;
vypis; if p<>nil then p.inorder;
end;
procedure TStrom.postorder;
begin if l<>nil then l.postorder;
if p<>nil then p.postorder;
vypis;
end;
Ďalšie pojmy
otec = predchodca; syn = nasledovník dva stromy sú podobné, ak majú rovnakú štruktúru
(rovnaký tvar) jeden strom je kópiou druhého, ak sú podobné a
majú rovnaký obsah vrcholov úrovne: každý vrchol v strome má svoju úroveň
(level):
koreň je v úrovni 0; jeho synovia sú úrovne 1 synovia vrcholu úrovne U majú úroveň U+1 v každej úrovni U je max. 2U vrcholov úplný strom úrovne U má vo všetkých úrovniach
(0 až U) maximálny počet vrcholov šírka stromu = najväčší počet vrcholov na jednej
úrovni
všetky hodnoty naľavo od otca sú menšie ako otec
všetky hodnoty napravo od otca sú väčšie ako otec
všetky podstromy sú tiež BVS výpis pomocou algoritmu inorder vypíše
utriedenú postupnosť
Binárny vyhľadávací strom
type prvok = integer; TVrchol = class info:prvok; l,p:TVrchol; constructor Create(i:prvok; nl,np:TVrchol); function text:string; virtual; end;
definíciu stromu rozdelíme na definíciu vrcholu stromu:
constructor vrchol.Create(i:prvok; nl,np:TVrchol);begin info:=i; l:=nl; p:=np;end;
function vrchol.text:string;begin Result:=IntToStr(info);end;
type TBVStrom = class private koren:TVrchol; public constructor Create; procedure vypis; function hladaj(i:prvok):TVrchol; procedure vloz(i:prvok); procedure zrus(i:prvok); end;
a trieda strom obsahuje len smerník na koreň stromu:
constructor TBVStrom.Create;begin koren:=nil;end;procedure TBVStrom.vypis; procedure vypis1(s:TVrchol); begin if s=nil then exit; Form1.Memo1.Lines.Add(s.text); vypis1(s.l); vypis1(s.p); end;begin vypis1(koren); end;
algoritmus sa postupne vnára do stromu, pričom na základe hodnoty vo vrchole sa rozhoduje, či pokračuje vľavo alebo vpravo
keď nenájde vrchol, vráti nil
Hľadanie v binárnom vyhľadávacom strome
function TBVStrom.hladaj(i:prvok):TVrchol;begin Result:=koren; while (Result<>nil) and (Result.info<>i) do if Result.info>i then Result:=Result.l else Result:=Result.p;end;
hľadanie v BVS:
najprv nájde miesto, kam by sa dal zavesiť nový vrchol (ako list), pričom sa podľa hodnoty vo vrchole rozhoduje, či pokračuje vľavo alebo vpravo
ak vrchol s danou hodnotou nájde, tak do stromu nový vrchol nevloží, ale skončí:
Vloženie nového prvku tak, aby strom ostal BVS
procedure TBVStrom.vloz(i:prvok);procedure vloz1(var s:TVrchol); begin if s=nil then s:=vrchol.Create(i,nil,nil) else if s.info=i then // nič, lebo sa našiel else if s.info>i then vloz1(s.l) else vloz1(s.p) end;
begin vloz1(koren);end;
vloženie novej hodnoty do BVS:
problém je iba s rušením vrcholu, ktorý má oboch synov - daný algoritmus nájde minimum v pravom podstrome vrcholu, toto minimum vyhodí a jeho hodnotu dá namiesto rušeného vrcholu:
Rušenie vrcholu tak, aby ostal strom BVS
procedure TBVStrom.zrus(i:prvok);
function zrusmin(var s:TVrchol):prvok; var q:TVrchol; begin if s.l=nil then begin Result:=s.info; q:=s; s:=s.p; q.Free end else Result:=zrusmin(s.l) end;
vyhodenie vrcholu z BVS:
procedure zrus1(var s:TVrchol); begin if s=nil then // nič else if s.info>i then zrus1(s.l) else if s.info<i then zrus1(s.p) else if (s.l=nil) and (s.p=nil) then begin s.Free; s:=nil end else if s.l=nil then s:=s.p else if s.p=nil then s:=s.l else s.info:=zrusmin(s.p) // z pravého podstromu minimálny prvok end;
begin zrus1(koren);end;