Escolar Documentos
Profissional Documentos
Cultura Documentos
Procedeul clasic de construire a arborelui binar de cutare ne d un arbore a crui form depinde foarte mult de ordinea n care sunt furnizate valorile nodurilor. n cazul cel mai general nu obinem un arbore de nlime minim.
Cazul cel mai favorabil, n care obinem nlime minim, este cel n care ni se furnizeaz pe rnd mijloacele intervalelor (subintervalelor) vectorului sortat. Cazul cel mai nefavorabil este cel n care valorile vin n ordine cresctoare (sau descresctoare), caz n care arborele binar de cutare obinut este degenerat (e chiar o list nlnuit, cu legturile date de fii drepi, cei stngi fiind toi nil (cresctor)). Problem: cum modificm algoritmul de construcie astfel nct s obinem nlime minim pentru arbore, pentru a mbunti timpul de cutare? S observm c la inserarea unui nou element crete cu 1 nlimea subarborelui n care s-a fcut inseria. Ne propunem, pentru noua metod de construcie, urmtorul criteriu: diferena dintre nlimile fiului stng i cel drept s nu depeasc pe 1.
bal=
Informaia despre valoarea factorului de echilibru n fiecare nod p al unui arbore o vom scrie ntr-un nou cmp al lui p, cmpul bal: -1..1. Algoritm de inserare - cu operatii suplimentare, re-echilibrari
p A
p A
p A
(a) p.bal=1
(b) p.bal=0
p A
(c) p.bal=-1
p A
p A
X
noul p.bal=0 (a)
X
noul p.bal=-1 (b)
X
(c)
p A
p A q q B
q B
X (A)
X
(A)
p A
(2)
(3)
p B (2)
q B
(1)
(1)
X X
(A) (A*)
Trecerea de la (A) la (A*) s.n. rotaie SS (Stnga-Stnga): (1) p.left:= q.right (2) q.right:= p {nainte de reasignarea lui p calculm noul factor de echilibru n A} p.bal:= 0 (3) p:= q urmat de calcularea factorului de echilibru pentru noul arbore: p.bal= 0.
Nu putem folosi acelai procedeu ca la (A), deoarece am obine un arbore neechilibrat. Desfurnd subarborele drept al lui q, obinem situaia din figura (B), unde noul nod inserat este fie Y, fie X, iar cazul (A') devine Cazul (B): Reechilibrm resetind legaturile (1), (2), (3), (4), (5)
(5) p (5) p C
(2)
A
q B (2)
(1)
(4) r C (3) B
(4)
A
(1) (3)
X
X (B) Y
(B*)
(1) q.right:=r.left
(2) r.left:=q (3) p.left:=r.right (4) r.right:=p
end; (5) p:=r {reasignarea pointerului ctre rdcin} Urmeaz apoi calculul factorului de echilibru pentru arborele din figura (B*) reechilibrat
p.bal:=0 Trecerea de la arborele de tip (B) la (B*) poart numele de rotaie SD (Stnga-Dreapta).
Cele spuse mai sus se aplic i pentru cazul n care se insereaz un nod nou pe subarborele drept al unui arbore de rdcin p. Vom avea atunci nc dou cazuri n care trebuie s facem reechilibrarea, simetricele cazurilor (A) i (B), care se trateaz analog. Simetricul cazului (A) va conduce la rotaie DD, iar al cazului (B) la rotaie DS.
Procedura recursiv Search(x, p) care caut i eventual insereaz un nod nou x n arborele de rdcin p se va modifica. n lista de parametri mai apare o variabil boolean, h, ce se transmite procedurii apelatoare, cu semnificaia: h= true, dac s-a modificat nlimea arborelui de rdcin p false, n caz contrar . Observm c n ambele cazuri de reechilibrare, nlimea arborelui reechilibrat este egal cu nlimea arborelui dinainte de inseria care a stricat echilibrul, deci dup reechilibrri h trebuie s ia valoarea false. Modificarea procedurii Search se face n felul urmtor: dup fiecare apel al ei, se testeaz h, iar dac h= true, avem de tratat separat cazurile pentru cele trei valori ale lui p.bal.
Procedura SearchIns (x, p) este o procedur recursiv care caut valoarea x n arborele binar de cutare de rdcin p i o insereaz dac nu o gsete, iar dac o gsete incrementeaz cmpul contor al nodului respectiv.
procedure SearchIns (x: integer; var p: pnod); begin if p= nil then {x nu a fost gsit i va fi inserat} begin new (p)
with p do begin {completarea cmpurilor noului nod} info:= x contor:= 1 left:= nil right:= nil end end
if x<p.info then
else {p<>nil}
SearchIns (x, p..right) else {x a fost gsit i se incrementeaz contorul} p.contor:= p.contor + 1
endproc {SearchIns}
p A
p A
p A
(a) p.bal=1
(b) p.bal=0
p A
(c) p.bal=-1
p A
p A
X
noul p.bal=0 (a)
X
noul p.bal=-1 (b)
X
(c)
Pentru nodurile unui arbore AVL vom folosi urmtoarele definiii de tip:
t y p e l e g = n o d ;
: i
t e
t , r
t : l
: -
. . 1
procedure Search (x:integer; var p;leg; var h:boolean); var q,r:leg; begin if p=nil then {inserare nod} begin new(p); with p do begin info:=x; left:=nil; right:=nil; bal:=0 {apare acum} end h:=true; end else if x<p.info then begin Search (x, p.left, h); {de aici ncepe modificarea fa de SearchIns}
if h then {a crescut nlimea ramurii stngi} case p.bal of 1: {acum cele dou ramuri ale lui p sunt egale} begin p.bal:=0; h:=false; end 0: {ramura din stnga e mai lung} p.bal:= -1 {h rmne true} -1: {reechilibrm}
...
-1: {reechilibrm} begin q:=p.left; if q.bal= -1 then {cazul (A) rotaie SS} begin p.left:=q.right; {1} q.right:=p; {2} p.bal:=0; p:=q {3} end else {cazul (B) rotaie SD} begin r:=q.right; q.right:=r.left; {1} r.left:=q; {2} p.left:=r.right; {3} r.right:=p; {4}
if r.bal=-1 then {s-a inserat X pe r.left} begin q.bal:=0; p.bal:=1; end else {s-a inserat Y pe r.right} begin q.bal:=-1; p.bal:=0; end; p:=r {5} end; {caz (B) rotatie SD} p.bal:=0; h:=false
end { case p.bal=-1} end{case} end {inserarea cu re-echilibrare pe ramura stng}
else{x>=p.info}{inserarea cu re-echilibrare pe ramura stng} if x>p.info then begin Search (x, p.right, h); if h then {a crescut nlimea ramurii drepte} case p.bal of -1: {cele dou ramuri ale lui p au devenit egale} begin p.bal:=0; h:=false; end 0: {ramura dreapt e mai lung} p.bal:=1 {h rmne true} 1: {reechilibrm}
{analog}
50
50 q
50
40
40
40
30
50
30
Se insereaz 50
Se insereaz 40
40 p 30 50
40
40
30
q
50
35
50
35
35
30
37
37
Se insereaz 35
40
q 35 r 30 37 30 50 35
37
40
39
50
37 p 35 40
37
35
45
q 30
39 r 50
30
40
50
45
55
39
42
55
42 Se insereaz 45 i 55. Apoi se insereaz 42. E nevoie de re-echilibrare n 40. Rotaie DS.