You are on page 1of 5

Arbori echilibrati AVL Algoritmul de insertie a arborelui va produce arbori de cautare valabili pentru orice date de intrare, dar

inca exista posibilitatea nedorita ca sa rezulte un arbore degenerat. O solutie a problemei mentinerii unui arbore de cautare valabil a fost descoperita in 1962 de Andelson-Velskii si Landis. Metoda lor necesita numai doi biti in plus pe nod si nu a utilizat niciodata mai mult de O(log N) operatii de cautare in arbore sau de inserare a unui item. De fapt, vom vedea ca abordarea lor va conduce la o tehnica generala buna pentru reprezentarea listelor liniare arbitrare de lungime N, astfel incat fiecare din urmatoarele operatii sa poata fi facuta in doar O(log N) unitati de timp: i) Gasirea unui item avand o cheie data. ii) Gasirea celui de-al k-ulea item, fiind dat k. iii) Inserarea unui item intr-un anumit loc. iv) Stergerea unui item specificat. Daca utilizam alocarea secventiala pentru liste liniare, operatiile (i) si (ii) sunt eficiente, dar operatiile (iii) si (iv) necesita N pasi; pe de alta parte, daca utilizam alocarea inlantuita, operatiile (iii) si (iv) sunt eficiente dar operatiile (i) si (ii) necesita N pasi. O reprezentare tip arbore a listelor liniare poate face toate operatiile in O(log N) pasi. Pot fi facute, de asemenea, si alte operatii standard cu eficienta comparabila, ca de exemplu concatenarea listelor. Metoda obtinerii acestora implica ceea ce vom denumi arbori echilibrati AVL. Oricum, in aplicatiile care nu implica toate patru operatiile, putem sa le realizam cu substantial mai putina incarcare si programare mai simpla. Mai mult, nu este avantajos sa folosim arbori echilibrati AVL decat daca N este destul de mare. Arborii echilibrati AVL sunt adecvati mai ales pentru stocarea interna de date; intrucat memoriile interne par sa creasca incontinuu odata cu trecerea timpului, arborii echilibrati AVL devin din ce in ce mai importanti. Un arbore binar este denumit echilibrat daca inaltimea fiecarui varf din subarborele stang nu difera cu mai mult de 1 de inaltimea celor din subarborele drept. Factorul de echilibru pentru fiecare varf este, prin definitie, inaltimea subarborelui drept minus inaltimea subarborelui drept. Daca un arbore binar este echilibrat, atunci factorul de echilibru pentru fiecare varf este 1, 0 sau -1. O clasa importanta de arbori echilibrati este clasa arborilor Fibonacci, definiti dupa cum urmeaza: Consideram mai intai sirul lui Fibonacci (Fn)n>=1, definit prin F1 = F2 = 1 si Fn+2 = Fn+1 + Fn pentru fiecare n >= 1. (formula 1) Ca sa gasim o formula explicita pentru numerele lui Fibonacci, trebuie sa ajungem la o solutie recurenta (in formula 1) de forma Fn = rn. Urmeaza ca r sa verifice ecuatia: r2 r 1 = 0 cu solutiile r1,2 = (1 5)/ 2. Prin urmare solutia generala a formulei 1 este Fn = C1r1n + C2r2n unde constantele C1, C2 se vor determina din conditiile initiale F1 = 1 si F2 = 1. Prin urmare rezolvand sistemul de ecuatii liniare C1(1 + 5)/ 2 + C2(1 5)/ 2 = 1 C1(3 + 5)/ 2 + C2(3 5)/ 2 = 1 Gasim C1 = 1/ 5 si C2 = 1/ 5, deci

Fn = 1/ 5 [(1 + 5)/ 2]n 1/ 5 [(1 5)/ 2]n care se numeste formula Binet pentru numerele lui Fibonacci. Primii termeni ai sirului lui Fibonacci sunt: 1, 1, 2, 3, 5, 8, 13, 21,, 34, 55, 89, ... Arborii Fibonacci, dedusi din FTk cu k = 0, 1, 2, ... sunt denumiti arbori binari definiti recurent dupa cum urmeaza: FT0 si FT1 consista fiecare intr-un singur varf extern: 0 . Acum pentru fiecare k >= 2, arborele Fibonacci de ordin k, FTk are radacina Fk; subarborele stang este FTk-1 iar subarborele drept este FTk-2, avand toate etichetele varfurilor (interne si externe) incrementate cu Fk, eticheta radacinii lui FTk. Lema 1 : (contine proprietatile de baza ale arborilor Fibonacci) Pentru fiecare k >= 1, arborele Fibonacci FTk este un arbore echilibrat avand inaltimea h(FTk) = k 1, Fk+1 varfuri externe si Fk+1 1 varfuri interne. Demonstratie : Pentru k = 1 si k = 2 proprietatea este verificata. Presupunem ca este adevarata pentru toti arborii Fibonacci FTk` cu k` < k si fie FTk un arbore Fibonacci de ordinul k (k >= 3). Atunci din definitia recursiva gasim h(FTk) = h(FTk-1) + 1 = k 1, numarul varfurilor externe ale lui FTk este egal cu Fk + Fk-1 = Fk+1, deci numarul varfurilor interne este egal cu Fk+1 1. Proprietatea de echilibru este verificata de ipoteza de inductie pentru toate varfurile diferite de radacina lui FTk. Pentru radacina lui FTk subarborele lui stang are inaltimea k 2 iar subarborele drept k 3, deci si FTk este un arbore echilibrat. Aceasta definitie a echilibrului reprezinta un compromis intre arborii binari optimi (cu toate varfurile externe pe doua nivele adiacente) si arborii binari arbitrari (nerestrictionati). Este deci natural sa ne intrebam cat de aproape de optim poate fi un arbore echilibrat. Raspunsul este: caile lui de cautare nu vor fi niciodata la mai mult de 45% din optim. Teorema 2 : Inaltimea unui arbore echilibrat T cu N varfuri interne va fi intotdeauna intre log2(N + 1) si 1,4404 log2(N + 2) 0,328. Demonstratie : Un arbore binar de inaltime h nu poate avea mai mult de 2h varfuri externe; deci N + 1 <= 2h(T) adica h(T) <= log2(N + 1). Pentru a afla valoarea maxima a lui h, punem problema invers si cautam numarul minim de varfuri interne posibile intr-un arbore echilibrat de inaltime h. Fie Th un astfel de arbore cu cele mai putine varfuri posibile; unul din subarborii din radacina, sa zicem subarborele stang, are inaltimea h 1, iar celalalt subarbore are inaltimea h 1 sau h 2. Din moment ce vrem ca Th sa aiba numar minim de varfuri vom presupune ca subarborele stang are inaltimea h 1, iar subarborele drept h 2. Deci putem presupune ca subarborele stang este Th-1, iar cel drept Th-2. Acest argument ne arata ca putem demonstra prin inductie ca arborele Fibonacci de ordin h + 1, F Th+1, are cele mai putine varfuri posibile dintre toti arborii echilibrati de inaltime h si acest numar minim de varfuri este Fh+2 1 din Lema 1. Astfel N >= Fh+2 1 = 1/ 5 [(1 + 5)/ 2]h+2 1/ 5 [(1 5)/ 2]h+2 1 In aceasta expresie, [(1 5)/ 2 (1, 0), deci 1/ 5 [(1 5)/ 2]h+2 >= 1 si N >= 1/ 5h+2 2, unde = (1 + 5)/ 2 > 1. Rezulta ca log2(N + 2) >= (h +2) log2 1/2 log25, deci h = h(T) <= [log2(N + 2)/ log2] + [log25/ 2log2] 2. Acum 1/ log2 < 1,4404 si [log25 /2log2] 2 < 0,328

Demonstratia acestei teoreme arata ca o cautare intr-un arbore echilibrat AVL va necesita mai mult decat 25 comparari doar daca arborele contine cel putin F27 1 = 196417 varfuri. Sa consideram acum ce se intampla cand un nou varf este inserat intr-un arbore echilibrat folosind insertia pentru arbori. Problema survine cand avem un varf cu un factor de echilibru de 1, al carui subarbore drept a devenit mai mare dupa insertie; sau, in paralel, daca factorul de echilibru este 1 si subarborele stang a devenit mai mare, cazuri in care va fi nevoie de cateva modificari. Nu este dificil de vazut ca exista, in principiu, doar doua cazuri care cauzeaza probleme: Doua alte cazuri identice in esenta vor aparea daca vom reflecta aceste diagrame, interschimband stanga cu dreapta. In aceste diagrame dreptunghiurile , , , reprezinta subarbori avand indicate inaltimile respective. Cazul 1 are loc cand un element nou a crescut inaltimea subarborelui drept de varf B de la h la h + 1, iar cazul 2 are loc cand un element nou a crescut inaltimea subarborelui stang de varf B. In al doilea caz avem fie h = 0 (astfel incat X insusi este un varf nou), fie varful X are doi subarbori de inaltimi (h 1, h) sau (h, h 1). Transformarile simple vor reface echilibrul in ambele cazuri de mai sus, pastrand in acest timp simetria varfurilor arborelui si inaltimea subarborelui care este reechilibrat: In cazul 1 pur si simplu rotim arborele la stanga, atasand lui A in locul lui B, si schimband radacina din A in B. Aceasta transformare este ca si aplicarea asociativitatii intr-o formula algebrica, inlocuind () cu (). In cazul 2 am folosit dubla rotatie, rotind mai intai (X, B) la dreapta, apoi (A, X) la stanga; in acest caz X este noua radacina a arborelui considerat. In ambele cazuri doar putine legaturi ale arborelui au trebuit schimbate (3 in primul caz si 5 in al doilea caz). In plus, noii arbori au inaltimea h + 2, care este exact inaltimea de dinainte de insertie; deci restul arborelui (daca exista) care a existat initial din varful A ramane intotdeauna echilibrat. Urmatorul algoritm evita folosirea stivei pentru a tine cont de varfurile care vor fi afectate in procesul de reechilibrare. Algoritmul A (Cautarea si insertia intr-un arbore echilibrat) Dandu-se o tabela de inregistrari care formeaza un arbore binar echilibrat ca mai sus, acest algoritm cauta un argument dat K. Daca K nu este in tabela, este inserat in cel mai apropiat loc din arbore un nou varf continand K, iar arborele este reechilibrat daca este necesar. Varfurile arborelui presupunem ca ar contine campurile din Algoritmul T (cautarea si insertia in arbore): KEY, LLINK si RLINK. Avem, de asemenea, un nou camp: B(P) = factorul de echilibru al lui NODE(P), inaltimea subarborelui drept minus inaltimea subarborelui stang; acest camp contine intotdeauna 1, 0 sau 1. Un varf superior special apare in partea de sus a arborelui, in locatia HEAD; valoarea lui RLINK(HEAD) este un pointer spre radacina arborelui, iar LLINK(HEAD) este utilizat sa urmareasca intreaga inaltime a arborelui. Presupunem ca arborele este nevid, astfel incat RLINK(HEAD) . Prin conventie in prezentare, algoritmul utilizeaza notatia LINK(a, P) sinonima pentru LLINK(P) daca a = 1 si pentru RLINK(P) daca a = 1. 1.Set T HEAD, S P RLINK(HEAD). (Pointerul variabil P se va deplasa in jos in cadrul arborelui; S va indica locul unde reechilibrarea va fi necesara, iar T va arata intotdeauna tatal lui S).

2.If K < KEY(P), go to 3; if K > KEY(P), go to 4; si if K = KEY(P) algoritmul se termina cu succes. 3.Set Q LLINK(P). If Q = , set Q AVAIL si LLINK(P) Q si go to step 5. Altfel if B(Q) 0, set T P si S Q. In sfarsit set P Q si return to step 2. 4.Set Q RLINK(P). If Q = , set Q AVAIL si RLINK(P) Q si go to step 5. Altfel if B(Q) 0, set T P si S Q. In sfarsit set P Q si return to step 2. 5.Set KEY(Q) K, LLINK(Q) RLINK(Q) , B(Q) 0. (Sunt initializate campurile lui NODE(Q)) 6.If K < KEY(S), set R P LLINK(S), altfel set R P RLINK(S). Apoi repeta urmatoarea operatie de zero sau de mai multe ori, pana cand P = Q: If K < KEY(P) set B(P) 1 si P LLINK(P); if K > KEY(P), set B(P) 1 si P RLINK(P); if K = KEY(P), then P = Q si putem merge la pasul urmator. (Factorul de echilibru pentru varfurile dintre S si Q au fost schimbate de la 0 la 1) 7.If K < KEY(S) set a 1, altfel set a 1. Iau nastere cateva cazuri noi: i)If B(S) = 0 (arborele a crescut mai inalt), set B(S) a, LLINK(HEAD) LLINK(HEAD) + 1, iar algoritmul se termina. ii)If B(S) = a (arborele a devenit mai echilibrat), set B(S) 0, iar algoritmul se termina. iii)If B(S) = a (arborele a devenit neechilibrat), go to step 8 if B(R) = a, sau go to step 9 if B(R) = a. (Cazul (iii) corespunde cazurilor 1 si 2 insertia unui varf nou intr-un arbore echilibrat cand a = 1; S si R indica varfurile A, respectiv B, iar LINK( a, S) indica pe , LINK( a, R) indica pe (sau pe X in cazul 2), etc.) 8.Set P R, LINK(a, S) LINK( a, R), LINK( a, R) S, B(S) B(R) 0. Go to 10. (rotatie simpla) 9.Set P LINK( a, R), LINK( a, R) LINK(a, P), LINK(a, P) R, LINK(a, S) LINK( a, P), LINK( a, P) S. Acum set (B(S), B(R)) i)( a, 0) if B(P) = a ii)(0, 0) if B(P) = 0 iii)(0, a) if B(P) = a; si apoi set B(P) 0. (rotatie dubla) 10.If S = RLINK(T) then set RLINK(T) P, altfel set LLINK(T) P. (P indica noua radacina iar T indica tatal vechii radacini) Acest algoritm este cam lung, dar se poate imparti in trei parti simple: pasii 1 4 fac cautarea, pasii 5 7 insereaza un varf nou, iar pasii 8 10 reechilibreaza arborele daca este necesar. Acest algoritm necesita in jur de ClogN unitati de timp, pentru un C constant, conform teoremei 2. Consideram un exemplu in cele ce urmeaza. Dupa pasul 7, a 1 deoarece K > KEY(S), B(S) = a = 1, iar arborele s-a dezechilibrat; acum este necesara o rotatie dubla intrucat B(R) = 1 = a etc. Fig. 1 : Insertia unui varf nou Q la pasii 3, 4 si 5. T este tatal lui S; B(S) 0 dar toti factorii de echilibru ai varfurilor dintre S si Q sunt egali cu zero. Fig. 2 : Schimbarea factorilor de echilibru pentru varfurile dintre S si Q in 1 la pasul 6 si definirea pointer-ului R ca radacina subarborelui drept (stang) al lui S, depinzand daca K > KEY(S) sau K < KEY(S).

Mentionam ca daca B(S) = 0 la pasul 7i) atunci S indica radacina arborelui, astfel incat S = RLINK(HEAD) si toate varfurile dintre S si Q au un factor de echilibru egal cu zero.

You might also like