You are on page 1of 11

Arbori AVL

Definire: Arborii binari de cutare echilibrai AVL sunt arborii binari de cutare care au urmtoarele proprieti: pentru fiecare nod din arbore, nlimea subarborelui stng difer de nlimea subarborelui drept prin maxim un nod; fiecare subarbore este un arbore binar de cutare AVL. Numele AVL este dat de numele inventatorilor lui: Adelson, Veliskii i Landis.

Inserarea unui nod ntr-un arbore AVL se face n dou etape. n prima etap se realizeaz inserarea nodului ca la o inserare obinuit ntrun arbore binar de cutare, iar apoi, dac este cazul se echilibreaz arborele.
1

Echilibrarea dac este cazul se face printr-o rotaie. Sunt patru cazuri distincte de rotaie. Rotaiile pot fi simple sau duble. Cele patru rotaii sunt: Rotaie stnga Rotaie dreapta Rotaie stnga-dreapta Rotaie dreapta-stnga Operatiile de cautare, insertie, stergere a unui nod cu cheia data n arbori echilibrati, se fac cu un efort de calcul de O(log n) unitati de timp, consecinta directa a teoremei demonstrate de Adelson, Velskii si Landis ce garanteaza ca un arbore echilibrat nu va fi niciodata cu mai mult de 45% mai nalt dect omologul sau perfect echilibrat, oricare ar fi numarul sau de noduri. Operaii pe arbori AVL: Tehnica inseriei nodurilor n arbori echilibrai AVL. Dndu-se un arbore cu radacina R si avnd subarborii stng si drept notati cu S si D, de nltimi hs si hd, la insertia unui nod n S se disting trei cazuri:
2

1. hs=hd, n urma insertiei, S si D devin de naltimi inegale, verificnd nsa criteriul echilibrului; 2. hs<hd, n urma insertiei S si D devin de naltimi egale, deci echilibrul se mbunatateste; 3. hs>hd, criteriul echilibrului nu se mai verifica, arborele trebuie reechilibrat. Cazurile posibile care pot duce la necesitatea reechilibrrii se pot sintetiza n urmtoarele, innd cont de subarborele n care se face inseria (subarborele stng sau drept) si de locul in cadrul subarborelui. Reechilibrarea la inseria n arbori AVL - Caz 1 stnga:

Reechilibrarea la inseria n arbori AVL - Caz 2

stnga-dreapta:

Reechilibrarea la inseria n arbori AVL - Caz 1 dreapta:

Reechilibrarea la inseria n arbori AVL - Caz 2 dreapta- stnga:

Un algoritm pentru insertie si reechilibrare depinde de maniera n care e memorata informatia referitoare la situatia echilibrului arborelui.

Cutarea ntr-un arbore AVL. Cutarea ntr-un arbore AVL se face la fel ca ntr-un arbore binar de cutare obisnuit, in plus adaugandu-se factorul de echilibru. Structura unui nod mpreun cu functia de inserare n nod este prezentat mai jos:
/* avl-tree.h */ typedef unsigned char Balance; typedef enum { Left, Right, Equal } Tree_balance; typedef struct tag_AVL_Tree { Tree_balance balance; int key; struct tag_AVL_Tree *l, *r; } AVL_Tree; AVL_Tree *avl_tree_insert (AVL_Tree *t, int k); /* avl-tree.c */ static int equilibration_required; static AVL_Tree *equilibrate_left (AVL_Tree *a); static AVL_Tree *equilibrate_right

(AVL_Tree *a); /* avl_tree_insert */ AVL_Tree *avl_tree_insert (AVL_Tree *t, int k) { if (t == NULL) { t = (AVL_Tree *) malloc (sizeof *t); t->balance = Equal; t->key = k; t->l = t->r = NULL; equilibration_required = 1; return t; } if (k > t->key) { t->r = avl_tree_insert (t->r, k); if (!equilibration_required) return t; switch (t->balance) { case Left: t->balance = Equal; equilibration_required = 0; return t; case Equal: t->balance = Right; return t; case Right: equilibration_required = 0;
6

return equilibrate_right (t); } } else if (k < t->key) { t->l = avl_tree_insert (t->l, k); if (!equilibration_required) return t; switch (t->balance) { case Left: equilibration_required = 0; return equilibrate_left (t); case Equal: t->balance = Left; return t; case Right: t->balance = Equal; equilibration_required = 0; return t; } } else { equilibration_required = 0; return t; } } static AVL_Tree *equilibrate_right (AVL_Tree *a) { AVL_Tree *b, *c;
7

b = a->r; if (b->balance == Right) { a->r = b->l; b->l = a; a->balance = b->balance = Equal; return b; } c = b->l; switch (c->balance) { case Equal: a->balance = Equal; b->balance = Equal; break; case Right: a->balance = Left; b->balance = Equal; break; case Left: a->balance = Equal; b->balance = Right; break; } a->r = c->l; b->l = c->r; c->balance = Equal; c->l = a; c->r = b; return c; } static AVL_Tree *equilibrate_left (AVL_Tree *a)
8

{ AVL_Tree *b, *c; b = a->l; if (b->balance == Left) { a->l = b->r; b->r = a; a->balance = b->balance = Equal; return b; } c = b->r; switch (c->balance) { case Equal: a->balance = Equal; b->balance = Equal; break; case Left: a->balance = Right; b->balance = Equal; break; case Right: a->balance = Equal; b->balance = Left; break; } a->l = c->r; b->r = c->l; c->balance = Equal; c->r = a; c->l = b; return c; }

Arbori Fibonacci Arborele Fibonacci este arborele in care informatia dintr-un nod fiu este mai mare sau egala decat informatia din radacina. Pentru a gasi naltimea maxim h a tuturor arborilor echilibrai cu n noduri, se considera o anumit nalime h si se ncearc construirea arborelui echilibrat cu numr minim de noduri. Se definesc astfel: 1. arborele vid este arborele Fibonacci de inaltime 0; 2. arborele cu un singur nod este arborele Fibonacci de inaltime 1; 3. daca Ah-1 si Ah-2 sunt arbori Fibonacci de inaltime h-1 si h-2, atunci Ah este un arbore Fibonacci de inaltime h; 4. nici un alt arbore nu este arbore Fibonacci. Numarul de noduri ale lui Ah este definit de urmatoarea relatie simpla de recurenta: N0=0, N1=1, Nh=Nh-1 + Nh-2. Exemplul 1: Sa se realizeze programul C++ pentru construirea si afisarea unui arbore Fibonacci.

10

Codul sursa pentru implementarea acestei probleme se gaseste in ex1.cpp. Exemplul 2: Sa se realizeze programul C++ pentru construirea si afisarea unui arbore AVL. Codul sursa pentru implementarea acestei probleme se gaseste in ex2.cpp.

11