Você está na página 1de 22

Arbori binari de cautare echilibrati AVL

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.

Arbori binari de cautare echilibrati AVL definitie


Definiie Se numete arbore binar de cutare echilibrat AVL (AdelsonVelskii-Landis) un arbore care n fiecare nod are proprietatea c nlimile subarborilor stng i drept difer cu cel mult 1. Pentru un nod dat, fie hl i hr nlimile subarborelui stng, respectiv drept. Avem trei situaii posibile n acest nod, codificate cu valorile variabilei bal= hr hl, pe care o numim factor de echilibru, n felul urmtor: 1, hl= hr -1 0, hl= hr -1, hl= hr+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)

In detaliu, cazul (c): ori (A), ori (A)

p A

p A q q B

q B

X (A)

X
(A)

Cazul (A): Putem reechilibra arborele resetnd legturile (1),(2),(3):


(3)

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

nainte de reasignarea lui p ctre noua rdcin trebuie s calculm noii


factori de echilibru n nodurile A (p) i B (q) n funcie de ce anume s-a inserat: nodul X sau nodul Y, cu secvena: if r.bal= -1 then {s-a inserat X} begin q..bal:=0; p.bal:=1 end

else {r..bal=1, adic s-a inserat Y} begin q.bal= -1; p..bal:=0

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}

else if x>p.info then

SearchIns (x, p..left)

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

Se insereaz 30. E nevoie de re-echilibrare n 50. Rotaie SS.

40 p 30 50

40

40

30
q

50

35

50

35

35

30

37

37

Se insereaz 35

Se insereaz 37. E nevoie de re-echilibrare n 30. Rotaie DD.

40
q 35 r 30 37 30 50 35

37

40

39

50

39 Se insereaz 39. E nevoie de re-echilibrare n 40. Rotaie SD.

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.

Você também pode gostar