Documente Academic
Documente Profesional
Documente Cultură
În acest capitol :
Diferenta esentiala este ca, în arborii balansati, un nod poate avea mai multi
descendenti (pâna la sute). Asemanarea este ca înaltimea arborelui este O(log n)
desi baza logaritmului (mult mai mare) da o înaltime corespunzator mai mica.
Aceasta este important pentru ca operatiile asupra arborelui, cum ar fi cautarea,
inserarea si stergerea au complexitati proportionale cu înaltimea arborelui.
Se vede din figura 10.1 cum arborii balansati generalizeaza arborii binari de
cautare.
Fig.10.
Cheile sunt consoane. Un nod contine n(x) chei si are n(x) + 1 descendenti.
Toate frunzele au aceeasi adancime. Nodurile albe marcheza drumul pentru
cautarea literei R.
Folosim arbori balansati în aplicatii în care datele nu pot intra în memoria Principala.
Algoritmii continuti în acest capitol copiaza anumite pagini de memorie de pe disc în memoria
principala si, pe cele care s-au modificat, le rescrie (înapoi pe disc). Modelul, din acest punct de
vedere, este urmatorul:
Fie x un pointer catre un obiect. Daca obiectul se afla în memoria principala, ne vom referi la
câmpuri ca de obicei (ex.KEY(x)). Daca obiectul se afla pe disc, vom face mai întâi o operatie de
citire CIT_DISK(x) a obiectului x si apoi ne putem referi la câmpurile lui. Daca s-au efectuat
modificari ale câmpurilor lui x ele vor fi actualizate pe disc prin scriere SCR_DISK(x).
fig. 10.2.
Figura 10.2 contine un exemplu de arbore balansat care are mai mult de un
miliard de chei.
KEY1(x),KEY2(x),...,KEYn(x)(x).
d) Daca x este nod intern (Frunza(x) este fals) atunci x mai contine
n(x)+ 1
2.Cheile din x separa cheile din descendenti adica daca kj este o cheie oarecare din
descendentul de la adresa Cj( x) cu j atunci
a)Fiecare nod, în afara de radacina, are cel putin t-1 chei si deci, daca
este intern, are cel putin t descendenti. Daca arborele este nevid, radacina
trebuie sa aiba cel putin o cheie .
b)Fiecare nod poate contine cel mult 2t-1 chei (un nod intern are cel
mult 2t descendenti). Spunem ca un nod este plin, daca are exact 2t-1 chei.
Cel mai simplu arbore balansat este cu t = 2 unde fiecare nod poate avea 2, 3
sau 4 descendenti.
Teorema
Demonstratie.
O sa pornim în demonstratie de la un arbore cu numar maxim de chei ca în
exemplul urmator.
Figl0.3
Daca arborele are înaltimea h, atunci numarul de noduri este minim când
radacina contine o cheie si celelalte noduri contin t-1 chei. În acest caz sunt 2
noduri la primul nivel, 2t la al doilea nivel, si asa mai departe pâna la nivelul h
unde sunt 2th-1.
n 1+ (t - 1) 2 t-1
=1 + 2(t-1)((th-1)/(t-1))= 2th - 1
i=1,h
Pentru urmatorii algoritmi vom presupune ca radacina arborelui este în memoria principala, deci
nu avem CIT_DISK pentru ea, dar este nevoie de SCR_DISK daca avem actualizari ale
câmpurilor radacinii. Mai presupnem ca orice alt nod are nevoie sa fie citit ca sa avem acces la
câmpurile lui.
i=l
rez = (x, i)
return
sdaca
rez = Nil
Return
altfel
Cheama CIT_DISK(ci(x))
return
sdaca
Pentru aceasta vom creea mai întâi un arbore vid si vom insera pe rând în el
noile chei. Avem nevoie mereu de locuri libere pe disc pe care le fumizeaza
ALOC_NOD().
B_TREE_CRE(T)
x = ALOC_NOD( )
Frunza(x) = True
n(x) = 0
SCR_DISK(x)
Rad(T) = x
Return
Daca un nod este plin, ca sa putem insera în continuare, el trebuie rupt în doua, ca
în figura 10.4:
Fig.l0.4
Nodul plin are 2t - 1 chei si cheia din mijloc (indice t) se duce în parinte,
presupus neplin.
B_TREE_RUP(x, k, y)
z = ALOC_NOD( )
Frunza(z) = Frunza(y)
n(z) = t-1
Pentru i = 1, t-1
spentru
Ci(z) = Ci+t(z)
spentru
sdaca
n(y) = t-1
Pentru i = n(x)+1,k+l,-1
Ci+l(X) = Ci(x)
spentru
Ci+l(X)= z
Pentru i = n(x), k, -1
KEYi+l(X) = KEYi(x)
spentru
KEYk(x)=KEY t(y)
n(x) = n(x) +1
SCR_D ISK( x)
SCR_DISK(y)
SCR_DISK(z)
return
B-TREE_INSERT(T, k)
r=Rad(T)
s = ALOC_NOD( )
Rad(T) = s
Frunza(T) = False
n(s) = 0
cl(S) = r
cheama B_TREE_RUP(s, 1, r)
cheama B_TREE_INS_NEPLIN(s,k)
altfel
Return
i = n(x)
KEYi+1(x) = KEYi(x)
i=i-1
Sciclu
KEYi+1(X) = k
n(x) = n(x) + 1
SCR_DISK(x)
i=i-1
sciclu
i=i+l
CIT_DISK(ci(x))
Cheama B_TREE_RUP(x,i,ci(x))
i=i+ 1
sdaca
sdaca
Cheama B_TREE_INS_NEPLIN(ci(x), k)
return
Exemple de inserari
( c ) este inserat Q
(d)
este inserat L
( e) este inserat F
Fig.10.6.
Contrar obiceiului dam aici numai câteva idei ale algoritmului de stergere:
1.Daca cheia k este în nodul x si x este frunza atunci se sterge pur si simplu
k din cheile lui x.
c.În alt caz (deci când si y si z au t-1 chei adica numarul minim) sterge
k din x si adresa ci+1(x) (catre z) iar cheile k si cele din z se introduc
împreuna cu pointerii în y continuând stergerea recursiv cu
B_TREE_STERG(y, k).
trebuie sa-l contina pe k. Daca ci(X) are numai t-l chei se executa 3.a. sau
3.b. apoi se reia recursiv pasul 3.
a.Daca ci(x) are numai t-l chei, dar are un frate alaturat (ci(x) sau
c+1(x) care au t chei atunci ci(x) primeste o noua cheie coborâta din x,
urmând sa se completeze numarul de chei cu cheia potrivita din fratele
care avea t chei.
b.Daca ci(x) si toti fratii lui alaturati (ci-1(x) sau ci+1(x)) au numai t-1
chei se unifica ci(x) cu unul dintre fratii alaturati coborând o cheie din
x ca cheie mediana în noul nod. (Actiunea este exact inversa ruperilor
si determina eliminarea ei si crearea unei noi radacini, aceasta
însemnând micsorarea înaltimii arborelui cu o unitate.
Exercitiul 1.
Exercitiul 2.