Documente Academic
Documente Profesional
Documente Cultură
Cuprins:
1. Ce este un arbore binar?
1.1. Definitii.
1.2. Tipuri de arbori binari.
1.3. Metode de stocare ale arborelui binar.
1.4. Metode de parcurgere ale arborelui binar.
1.5. Metode de traversare ale arborelui binar.
1.6. Parcurgerea in adancime.
1.7. Parcurgerea in latime.
1.8. Implementari.Implementarea succinta
1.9. Implementarea unui numar de n arbori in arbori binari.
2.1. Operatii.
2.2. Cautarea.
2.3. Inserarea unui nod.
2.4. Suprimarea unui nod.
2.5. Traversarea arborelui binar de cautare.
2.6. Sortarea arborelui binar de cautare.
2.7. Optimizarea arborelui binar de cautare.
In domeniul calculatoarelor, un arbore binar este structura de date abstracte in care fiecare
nod are cel mult doi fii.De obicei nodurile sunt denumite stang daca se afla in partea
stanga a arborelui (sau a unui sub-arore), si drept daca se afla in partea dreapta a arborelui
(sau a vreunui sub-arbore).O denumire mai utilizata pentru arborii binari este arbori
binari de cautare.
* Un arbore binar cu radacina este un arbore care porneste de la un nod radacina, iar
fiecare nod are cel mult doi descententi.
* Unarbore binar plin, sau arbore binar propriu, este un arbore in care fiecare nod are sau
nici un fiu sau doi fii.
* Un arbore binar perfect (denumit uneori arbore binar complet este un arbore binar plin
in care toate nodurile curente ("frunzele") sunt la aceasi adancime.
* Un arbore binar complet ar putea fi definit ca un arbore binar plin in care toate nodurile
curente au adancimea de n sau n-1 pentru oricare ar fi n.Ordonand un arbore binar, acesta
va deveni un arbore binar complet, adica toate nodurile-fii de la ultimul nivel trebuie sa
ocupe consecutiv locurile cele mai din stanga, pana cand nu mai ramane nici un loc
neocupat.De exemplu, daca doua noduri aflate in cel mai de jos nivel al arborelui ocupa
fiecare cate un loc rezultand astfel un alt loc liber intre cele doua noduri, atunci restul
nodurilor descendente vor fi strans marginite intre ele fara sa existe nici un loc
neocupat.Cu alte cuvinte, un arbore binar complet are nodurile curente ("frunza") fiecare
cu cate doi descendenti, neexistand ca printre acestea sa fie un nod curent cu numai un
singur descendent rezultant astfel un loc liber intre acestia.
* Un arbore binar complet cu radacina poate fi identificat printr-un vector liber.
* Unarbore binar aproape complet este un arbore in care fiecare nod al acestuia are un fiu
drept si un fiu stang.Detinerea unui nod-fiu stang nu implica necesitatea ca parintele sa
aiba neaparat si un nod-fiu drept.Adica, un arbore binar aproape complet este arborele
unde pentru un nod-fiu drept exista un descendent stang,insa nodul-fiu stang nu este
obligatoriu sa detina un descendent drept propriu.
Arborii binari poti fi deasemeni stocati intr-un tablou ca un tip de structura de date
implicita, si daca arborele este un arbore binar complet aceasta metoda nu lasa locuri
ramase neocupate in tablou.In acest aranjament compact, daca un nod are indicele i
descendentii lui pot fi gasiti la indicii 2i+1 si 2i+2, atat timp cat nodul-parinte al acestora
este gasit la indicele-nivel((i-1)/2)(declarand ca nodul radacina are indicele zero).Aceasta
metoda bebeficiaza de o stocare mai compacta a informatiilor in comparatie cu metoda
localizarii referintelor, efectuant in particular o traversare in preordine.Oricum, ea este
expansiva si nu utilizeaza un spatiu proportional cu 2h-n pentru un arbore cu inaltime h
cu un numar de n noduri.
In limabejele ce folosesc uniuni etichetate este limbajul ML, nodul unui arbore este
adesea o uniune etichetata a doua tipuri de noduri iar una dintre acestia este a reprezinta a
treia parte a datelor.Fiul stang si fiul drept si oricare dintre pot fi un nod curent (frunza),
care nu contin date si functii, asa cum sunt valorile nule intr-un limbaj cu referinte
(pointeri).
In exemplul de mai sus sirul structure are numai 2n+1 biti la sfarsit, unde n este numarul
nodurilor (interne).Nu se doreste sa se inmagazineze mai multe informatii decat poate
cuprinde sirul structura.Pentru a arata cum este posibil sa nu se piarda nici o informatie,
se va transforma datele de iesire inapoi intr-un arbore:
O metoda de a lamuri cele scrise mai sus este aceea ca fiecare nod-fiu se afla intr-o lista
inlantuita,si este inlantuit inpreuna cu celelalte noduri din partea dreapta, si nodul are
numai o referire catre inceputul listei sau in varful acestei liste, prin intermediul nodurilor
din partea stanga.
Arborele binar poate fi vazut prin structura arborelui initial prin faptul ca marginile negre
reprezinta primul descendent si marginile albastre reprezentand urmatorul
inlocuitor.Nodurile curente ale arborelui din stanga poate fi scrise in Lisp astfel: (((M N)
H I) C D ((O) (P) F (L)) acestea putind fi implementate in memorie in structura arborelui
din partea dreapta.
Aceasta operatie necesita un timp de executie O(log n) in cazul in care cerinta impune o
cautare de o complexitate medie, insa daca se comporta ineficient atunci algoritmul se va
executa intr-un timp de O(n) - adica arborele este neechilibrat si re-aranzeaza o lista
sortata.
2.3. Insertia. >>>
Metoda de insertie se efectueaza asemanator ca si metoda de cautare.Se incepe prin
verificarea valorii ce trebuie cautata cu valoarea nodului radacina.Daca valoarea ce
trebuie cautata nu este egala cu valoarea nodului radacina, atunci procedura de cautare se
va continua ori in structura sub-arborelui stang, ori in structura sub-arborelui drepta ca si
la procedeul de cautare.Eventual, se poate extinde un nod extern si se va adauga valoarea
ce trebuie cautata ca fiind un nod-fiu drept sau stang.Cu alte cuvinte, se poate examina
nodul radacina si se ve insera recursiv un nou nod in cadrul structurii sub-arborelui stang
daca valoarea ce trebuie cautata este mai mica sau egala cu valoarea nodului radacina,
sau in structura sub-arborelui daca valoarea cautata este mai mare ca si valoaera nodului
radacina.
Partea este reconstruita folosind un spatiu de È(log n) locatii de memorie in cazul in care
cerinta este de dificultate medie, iar in cel mai rau caz flolseste uin spatiu de Ù(n).In
fiecare versiune, aceasta operatie necesita un timp direct proportional cu inaltimea
arborelui in cazul in care acesta functioneaza ineficient, adica se efectueaza intr-un timp
de O(log n) in cazul (valabil pentru toti arbori creati) in care se rezolva o problema de
dificultate medie, insa aceasta va avea Ù(n2) in cazul in care se comporta ineficient.
O alta cale de a realiza insertia este prin inserarea in ordinea inserarii noii valori in
arbore, aceasta valoare este prima data comparata cu valoarea nodului radacina.Daca
aceasta valoare este mai mica decat valoarea nodului radacina atunci ea va fi comparata
cu valoarea nodului-fiu stang.Daca valoarea este mai mare, atunci ea va fi comparata cu
valoarea nodului-fiu drept.Acest pocedeu continua pana cand npoua valoarea inserata
este comparata cu un nod curent fiindu-i adaugata ca un nod-fiu (descendent) drept sau
stang.Pot fi mai multe metode de a insera o valoare in cadrul structurii arborilor binari de
cautare, insa aceasta este singura metoda care ataseaza nodurilor curente ale arborelui in
care se face insertia alte noi noduri fara sa fie afectata structura acestuia.
* Stergerea unui nod curent: Suprimarea (stergerea) unui nod curent care n-are
descendenti se face usor.
* Stergerea unui nod care are un nod-fiu: Se va sterge nodul si se va inlocui cu nodul-fiu.
* Stergerea unui nod cu doua noduri-fii: Se presupunem ca nodul este numit N.Se va
inlocui valoarea nodului N cu valoarea unui succesor parcurs in ordine (cel mai din
stanga nod-fiu al sub-arborelui drept) sau cu a predecesorului (cel mai din dreapta nod-fiu
al sub-arborelui stang).
Imaginea arata modalitatea de suprimare a nodurilor curente ale arborelui din mijloc.
Astfel se gaseste oricare predecesor sau succesor al arborelui parcurs in ordine, mutarea
lui in locul nodului N si stergerea lui.Astfel fiecare dintre aceste noduri trebuie sa aiba
mai putin de doua noduri-fii (caci altfel el nu poate fi un succesor sau predecesor in cazul
in care arborele in care se face suprimarea este parcurs in ordine), el putand fi sters
folosind cele doua cazuri prezentate mai sus.Intr-o buna implementare, in general este
recomandat sa se evite folosirea unuia dintre aceste noduri , deoarecea suprimarea lui ar
putea dezechilibra arborele.
Aici este prezentat un algoritm C++ care foloseste metoda destructiva a suprimarii (se va
presupune ca nodul care trebuie suprimat a fost deja gasit printr-o metoda de cautare):
def traversarea_arborelui_binar(nodarbore):
if nodarbore is None: return
stanga, valoarenod, dreapta = nodarbore
traversarea_arborelui_binar(stanga)
visit(valoarenod)
traversarea_arborelui_binar(dreapta)
Perioada de traversare a algoritmului necesita un timp de Ù(n) atunci cand acesta doreste
sa verifice fiecare nod.Algoritmul de traversare se executa intr- un timp determinat de
functia O(n)
def construieste_arbore_binar(valori):
arbore = None
for v in valori:
arbore = inasereaza_arborele_binar(arbore, v)
return arbore
def traverseaza_arbore_binar(nodarbore):
if nodarbore is None: return []
else:
stanga, valoare, dreapta = nodarbore
return (traverseaza_arbore_binar(stanga) + [valoare] +
traverseaza_arbore_binar(dreapta))
Aici este o varietate de scheme pentru a acoperii aceste "Nici unu"-uri cu arbori binari
simpli.Cel mai adesea utilizat este arborele binar echilibrat de cautare.Daca aceeasi
procedura este executata folosind de exemplu un arbore, atunci comportarea ineficienta
pentru toti este O(nlog n) care este o optiune asimptotica pentru o sortare prin
comparare.In practica, performanta scazuta in lucrul cu memoria "cache" si spatiul de
memorie folosit in cadrul unei sortari dedicate pe lucrul cu arbori (in particular pentru
alocarea nodurilor) realizeaza o sortare mult mai inferioara in comparatie cu alte sortari
optime asimptotice cum sunt sortarea rapida ("quick sort") si "heapsort" cand acestea
lucreaza cu liste statice sortate.Oricum, aceaste este una din cele mai eficiente metode de
sortare incrementala, prin fpatul ca se adauga termeni intr-o lista intr-o maniera rapida
atat timp cat lista este sortata.
Daca nu se cunoaste segventa in care elementele arborelui pot fi accesate timpuriu, atunci
se poate folosi un gen de arbore binar numit "splay" care functioneaza dupa metode
asimptotice care il determina sa se comporte eficient si sa fie stabil pentru putea sa-l
folosim in construirea unor segvente particulare pentru metodele de vizulalizare ale
arborilor.
Sunt mai multe tipuri de arbori binari de cautare.Arborii AVL si arborii rosii-negrii sun
doua forme de arbori binari echilibrati de cautare.Un arbore "splay" este un arbore binar
care muta fregvent si automat elementele din apropierea nodului radacina.Intr-un arbore
"treap" ("tree heap"), fiecare nod acorda o inalta prioritate nodulor-parinti.
Arborele AVL este numit dupa numele celor doi iventatorilor ai sai, G.M Andelson-
Velsky si E.M. Landis, care publicasera in anul 1962 iventia lor in revista pe care acestia
o editau in articolul intitulat "Un algoritm pentru organizarea informatiilor".
Factorul de echilibrare al unui nod este inaltimea sub-arborelui drept minus inaltimea
sub-arborelui stang ai acestuia.Un nod care are factorul de echilibru 1,0, sau -1 este
considerat echilibrat.Un nod cu un alt foactor de echlibru diferit de cei prezentati anterior
este considerat dezechilibrat, astfel fiind necesar reechilibrarea arborelui.Factorul de
echilibru pentru fiecare dintre cei doi sub-arbori este determinat direct la fiecare nod sau
calculat prin inaltimea sub-arborilor.
Exemplu de arbore non-avl.
Arborii AVL sunt adeseori comparati cu arborii rosii-negrii deoarece acestia suporta
acelasi set de operatii, iar un alt motiv este ca arborii rosii-negrii necesita un timp de
O(logn) pentru a efectua oricare din operatiile de baza.
Arborii AVL se comporta mai eficient in operatii decat arborii rosi-negrii in cazul in care
se abordeaza aplicatii intensiv vizualizate.Deasemeni algoritmul de echilibrare al
arborelui AVL este folosit foarte des in stinta calculatoarelor.
Daca factorul de echilibru din cauza inserarii la un nod devine 2 sau -2 atunci sub-
arborele acestui nod este dezechilibrat, astfel trebuind sa se efectueze o rotatie a
arborelui.Rotatia nu se va aplica daca sub-arborii sunt echilibrati.Oricum rotatia poate fi
facuta intr-un timp constant.
Pentru operatia de suprimare este necesara o perioada denumita O(h) pentru a vizualiza
structura arborelui in care se face suprimarea plus O(h) rotatii intr-o parcurgerea a
arboreului in adancime, astfel ca operatia de suprimare se executa in totalitate intr-un
timp definit O(log n).