Documente Academic
Documente Profesional
Documente Cultură
Arbori Echilibraţi
Arbori Echilibraţi
Arbori Echilibraţi
ARBORI ECHILIBRAŢI
23
10 27
3 18 2 2
10 27
3 18
Din analiza modului in care sunt poziţionate valorile, situaţia cea mai
puţin favorabilă ce caracterizează acest arbore binar de căutare este data
de cazul în care nodul ce conţine cheia cu valoarea 2 are o frecvenţă ridicată
de utilizare. Situaţia este generată de faptul ca cel mai lung drum de la
nodul rădăcină la un nod frunza este dat de drumul 23 – 10 – 3 – 2, de
lungime 4. Dimensiunea este determinată de numărul de comparări
necesare identificării nodului căutat.
Pe baza unei aranjări echilibrate a valorilor, acelaşi set de valori este
reprezentat de structura arborescenta următoare
10
3 23
2 18 27
Prin prisma cazului cel mai puţin favorabil, arborele din figura 14.3
este mai eficient decât cel anterior deoarece numărul maxim de comparări
necesare identificării oricărui nod din structura este egal cu 3.
În funcţie de numărul de elemente dintr-un arbore binar de căutare,
n, o structură echilibrată descrie o complexitate egală cu O(log2n) pentru
cel mai nefavorabil caz. În schimb, o structură arborescentă de acelaşi tip,
dar care nu este echilibrată, este caracterizată pentru cel mai nefavorabil
caz de o complexitate egală cu O(n).
Minimizarea efortului de regăsire a informaţiilor se obţine printr-o
aranjare echilibrata a valorilor pe ambii subarbori ai fiecărui nod.
14.2 Caracteristici ale arborilor AVL
în care funcţia max() este utilizată pentru a determina maximul dintre două
valori.
10 GE = 0
GE = -1 GE = 0
3 23
GE = 0 GE = 0 GE = 0
2 18 27
10 GE = -1
GE = -2 GE = 0
3 23
GE = -1 GE = 0 GE = 0
2 18 27
GE =0
? ?
GE = -2
GE = 0
NOD PIVOT 3 2
GE = -1 GE = 0
Z Y Y X
Y - Subarbore stang
fiu dreapta pivot
? ?
NOD PIVOT
GE = 0
3 2
GE = H1 – (H1 + 2) = -2
GE = 0
2 3
X Z
H1 H1+1 H1+1
GE = H1 – (H1 + 1) = -1
H1+2
Z Y Y X
H1+1 H1 H1
H1
pivot->Echilibru = 0;
FiuStanga->Echilibru = 0;
pivot = FiuStanga;
}
10 GE = 0
GE = 0 GE = 0
2 23
GE = 0 GE = 0
1 3 18 27
GE =0 GE = 0
Dacă prin inserarea sau ştergerea unui nod se ajunge în situaţia din
figura 14.9, reechilibrarea arborelui se realizează printr-o rotire simplă la
stânga.
10 GE = 1
GE = -1
GE = 2
2 23
GE =0 GE = 1
1 27
GE = 0
30
? ?
GE = 2
NOD PIVOT GE = 0
23 30
GE = 1 GE = 0
X - Subarbore stâng
pivot NOD FIU PE
X 30 DIRECTIA 23 Z
DEZECHILIBRULUI
Y Z X Y
Y - Subarbore stang
fiu stânga pivot
pivot = FiuDreapta;
}
10 GE = 1
GE = -1
GE = 0
2 27
GE =0 GE = 0 GE = 0
1 23 30
10 GE = 2
GE = -1
GE = -2
2 27
GE =0 GE = 1 GE = 0
1 23 30
GE = 0
GE = 1
16 24
GE = 0
26
10 GE = 2
GE = -1
GE = 2
2 23
GE =0 GE = 0 GE = -1
1 16 27
GE = 1
24 30
GE = 0
GE = 0 26
10 GE = 2 10 GE = 2
GE = -1 GE = -1
GE = -2 GE = -2
2 27 NOD PIVOT 2 27 NOD PIVOT
GE =0 GE = 1 GE =0 GE = -1 GE = 0
NOD FIU
1 23 30 1 24 30
GE = 0 GE = 1 GE = 0 GE = -1 GE = 0
16 24 23 26
GE = 0
26 GE = 0
A) ROTATIE SIMPLA LA STANGA 16 B) ROTATIE SIMPLA LA DREAPTA
10 GE = 1
GE = -1
GE = 0
2 24
GE =0 GE = -1 GE = 0
1 23 27
GE = 0 GE = 0 GE = 0
16 26 30
C) ARBORE REECHILIBRAT
Situaţia descrisă în tabelul anterior este utilizată pentru a defini mai eficient
metoda care implementează acest tip de rotaţie. Astfel este evitat efortul
suplimentar de a recalcula gradul de echilibru pentru cele trei noduri
afectate.
Clasa AVLArbore implementează această operaţie prin intermediul
metodei RotatieDublaDreapta ce primeşte ca parametrul referinţa nodului
pivot.
FiuStanga_FiuDreapta->Echilibru=0;
pivot = FiuStanga_FiuDreapta;
}
10 GE = 2
GE = -1
GE = 2
2 24
GE =0 GE = -1 GE = -1
1 23 27
GE = -1 GE = 0
26 30
GE = 0
25
10 GE = 2 10 GE = 2
GE = -1 GE = -1
NOD PIVOT GE = 2 NOD PIVOT GE = 2
2 24 2 24
GE =0 GE = -1 GE = -1 GE =0 GE = -1 GE = 1
NOD FIU NOD FIU
1 23 27 1 23 26
GE = -1 GE = 0 GE = 0 GE = 1
26 30 25 27
GE = 0
25 B) ROTATIE SIMPLA LA STANGA GE = 0 30
10 GE = 1
GE = -1
GE = 0
2 26
GE =0 GE = 0 GE = 1
1 24 27
GE = 0 GE = 0
23 25
GE = 0 30
C) ARBORE REECHILIBRAT
class AVLNod
{
private:
int Echilibru;
int Info;
AVLNod *st;
AVLNod *dr;
public:
//constructorii clasei
AVLNod(void);
AVLNod(int echilibru, int info, AVLNod * stanga, AVLNod *
dreapta);
//destructorul clasei
virtual ~AVLNod(void);
AVLNod::AVLNod(void)
{
Echilibru = 0;
Info = 0;
st = NULL;
dr = NULL;
}
AVLNod::AVLNod(int echilibru, int info, AVLNod * stanga, AVLNod *
dreapta)
{
Echilibru = echilibru;
Info = info;
st = stanga;
dr = dreapta;
}
class AVLArbore
{
public:
AVLNod *radacina;
public:
//constructorul clasei
AVLArbore(void);
//constructorul de copiere al clasei
AVLArbore(const AVLArbore & arbore);
//destructorul clasei
virtual ~AVLArbore(void);
//operatorul =
AVLArbore operator = (AVLArbore & arbore);
private:
void AVLInsert(AVLNod* &arbore,AVLNod * nodNou, int &
echilibruNou);
void AVLDelete(AVLNod* &arbore,const int Info,AVLNodeStack
&stiva);
10
Preordine: 10, 3, 2, 23, 18, 27
Inordine: 2, 3, 10, 18, 23, 27
Postordine: 2, 3, 18, 27, 23, 10
3 23
2 18 27
10 2 2
3 3
3 23
10 18
2 18 27 18 3 27
23 23
if(arbore == NULL){
arbore = nodNou;
arbore->Echilibru = 0;
echilibruNou = 1;
}
else
if(nodNou->Info<arbore->Info){
AVLInsert(arbore->st,nodNou,Reechilibrare);
if(Reechilibrare){
if(arbore->Echilibru == -1)
ReechilibrareSubarboreStang(arbore,echilibruNou);
else
if(arbore->Echilibru == 0){
arbore->Echilibru = -1;
echilibruNou = 1;
}
else{
arbore->Echilibru = 0;
echilibruNou = 0;
}
}
else
echilibruNou = 0;
}
else{
if(nodNou->Info>arbore->Info){
AVLInsert(arbore->dr, nodNou, Reechilibrare);
if(Reechilibrare){
if(arbore->Echilibru == -1){
arbore->Echilibru = 0;
echilibruNou = 0;
}
else
if(arbore->Echilibru == 0){
arbore->Echilibru = 1;
echilibruNou = 1;
}
else
ReechilibrareSubarboreDrept(arbore,echilibruNou);
}
else
echilibruNou = 0;
}
else
echilibruNou = 0;
}}
if(FiuStanga->Echilibru == -1){
RotatieSimplaDreapta(pivot);
echilibruNou = 0;
}
else
if(FiuStanga->Echilibru == 1){
RotatieDublaDreapta(pivot);
echilibruNou = 0;
}
else
//situatie specifica operatiei de stergere
if(FiuStanga->Echilibru == 0){
RotatieSimplaDreaptaStergere(pivot);
echilibruNou = 0;
}
}
- metoda ReechilibrareSubarboreDrept analizează cazurile de
dezechilibru la dreapta, reechilibrând pivotul prin una din cele
două tehnici de rotaţie la stânga;
if(FiuDreapta->Echilibru == 1){
RotatieSimplaStanga(pivot);
echilibruNou = 0;
}
else
if(FiuDreapta->Echilibru == -1){
RotatieDublaStanga(pivot);
echilibruNou = 0;
}
else
//situatie specifica operatiei de stergere
if(FiuDreapta->Echilibru == 0){
RotatieSimplaStangaStergere(pivot);
echilibruNou = 0;
}
}
int EchilibruNou = 0;
AVLInsert(RadacinaArbore,NodNou,EchilibruNou);
this->radacina = RadacinaArbore;
}
class AVLNodeStack
{
private:
NodeStack * VarfStiva;
public:
AVLNodeStack()
{
VarfStiva=NULL;
}
AVLNod* POP(){
if(this->VarfStiva==NULL)
return NULL;
else
{
NodeStack *elementSters = this->VarfStiva;
AVLNod* NodAuxiliar = this->VarfStiva->Nod;
this->VarfStiva = this->VarfStiva->next;
delete elementSters;
return NodAuxiliar;
}
}
void AfiseazaStiva()
{
NodeStack *temp = this->VarfStiva;
while(temp!=NULL)
{
printf("\n Nod in stiva este %d",temp->Nod->Info);
temp=temp->next;
}
}
};
47 35
stiva GE = -1
35
22 47 GE = -1
GE = 1
16 31 37 50
GE = -1 GE = -1 GE = 1
GE =0
9 27 32 42
GE =0 GE =0 GE =0
GE = -1
29
GE =0
22 47 GE = -2
GE = 1 22 37 GE =0
GE = 1
16 31 37
GE = -1 GE = -1 GE = 1 16 31
GE = -1 GE = -1 42 47
9 27 32 42 GE = 0 GE =0
GE =0 GE =0 GE =0
9 27 32
GE = -1 GE =0
29 GE =0 GE = -1
GE =0 29
GE =0
35 GE =0
31
GE = -2
GE =0
22 35 GE = -1
(2)
22 37 GE =0 GE =0
GE = 1
16 27 32 37 GE =0
16 (1) 31 42 47
GE = -1 GE = -1 GE = -1 GE = 1
GE = 0 GE =0
9 27 32 9 29 42 47
GE =0
GE =0 GE = -1 GE =0 GE =0 GE =0 GE = 0
29
GE =0
17 17 GE = 2
20
GE = 1 GE = -1
16 20 20 17 23
GE = 0 GE = 0 GE = -1 GE = 0
GE =0
19 23 19 23 19
GE =0 GE =0 GE =0 GE =0 GE =0
pivot->Echilibru += 1;
FiuStanga->Echilibru += 1;
pivot = FiuStanga;
}
pivot->Echilibru -=1;
FiuDreapta->Echilibru -= 1;
pivot = FiuDreapta;
}
15 negru
roşu roşu
3 23
2 18 27
class RNNod
{
int Info;
bool Culoare;
RNNod *st;
RNNod *dr;
RNNod *parinte;
};
15 nod bunic
nod părinte
nod unchi
3 23
nod analizat
2 18 27
43 43
43
25 78
25 78 25 78
14 14
25 78
nod nou
14
43
nod bunic
25 78
nod părinte
14 nod NULL
17 dezechilibru
nod nou
25 78 25 78
nod părinte
43 43
nod bunic
25 78 17 78
17 nod NULL 14 25
14
dezechilibru
nod bunic
17 78 17 89
nod parinte
14 25 89 14 25 78 95
nod nou
95
dezechilibru
17 89
17 89
14 25 95
14 25 78 95
43 43
Înlocuire cu unicul fiu al
nodului de şters
nod de şters
17 89 14 89
14 78 15 78
15
Figura 14.33 Cazul 1 de ştergere nod din arbore Roşu & Negru
Dacă nodul şters este de culoare neagră, iar fiul său este de culoare
roşie, figura 14.34, atunci arborele devine dezechilibrat pe drumul care
trece prin această zonă deoarece numărul de noduri negre este mai mic cu
unul. Reechilibrarea structurii arborescente se face în această situaţie prin
recolorarea în negru a nodului fiu. Astfel este refăcut numărul de noduri
negre.
43 43
Înlocuire cu unicul fiu al
nodului de şters
nod de şters
17 79 14 79
recolorat in
negru
14 54 83 15 54 83
15 48 59 80 48 59 80
Figura 14.34 Cazul 2 de ştergere nod din arbore Roşu & Negru
B nod bunic
32
nod părinte
nod unchi
P 25 79 U
nod nepot
nod de şters N1 N2
14 54 89
nod fiu 17 45 58 81
F
Următorul caz analizat este dat de figura 14.36 în care nodul cu valoarea
25 este şters. Situaţia este descrisă de ipotezele:
- nodul de şters este negru;
- unicul fiu al nodului de şters este negru;
- nodul unchi al nodului de şters este negru;
- nodul părinte este negru;
- nodurile nepoţi sunt negre.
B B
P 32 P 32
dezechilibru
nod de şters
U U
F
25 79 14 79
F N1 N2 N1 N2
14 54 89 10 17 54 89
10 17 45 58 81 45 58 81
Figura 14.36 Cazul 3 de ştergere nod din arbore Roşu & Negru
U U
F F
14 79 14 79
N1 N2 N1 N2
10 17 54 89 10 17 54 89
45 58 81 45 58 81
Figura 14.37 Soluţie de reechilibrare caz 3 pentru arbore Roşu & Negru
B B
P 22 P 22
dezechilibru
nod de şters
U U
F
15 69 4 69
F N1 N2 N1 N2
4 54 89 0 7 54 89
0 7 45 58 81 45 58 81
Figura 14.38 Cazul 4 de ştergere nod din arbore Roşu & Negru
P 22 P 22
dezechilibru
U U
F F
4 69 4 69
N1 N2 N1 N2
0 7 54 89 0 7 54 89
45 58 81 45 58 81
Figura 14.39 Soluţie de reechilibrare caz 4 pentru arbore Roşu & Negru
B B
P 32 P 32
dezechilibru
nod de şters
U U
F
25 79 14 79
F N1 N2 N1 N2
14 54 89 10 17 54 89
10 17 45 58 81 45 58 81
Figura 14.40 Cazul 5 de ştergere nod din arbore Roşu & Negru
U
F P
14 79 dezechilibru 32 N2
(2) 89
N1 N2 F N1
10 17 54 89 14 54 81
45 58 81 10 17 45 58
Figura 14.41 Soluţie de reechilibrare caz 5 pentru arbore Roşu & Negru
B B
U 79 Interschimbare culori U 79
dezechilibru
P P
32 N2 32 N2
89 89
F N1 F N1
14 54 81 14 54 81
10 17 45 58 10 17 45 58
Figura 14.42 Reechilibrare arbore Roşu & Negru din figura 14.41
P 22 P 22
dezechilibru
nod de şters
U U
F
15 69 4 69
F N1 N2 N1 N2
4 54 89 0 7 54 89
0 7 45 58 81 45 58 81
Figura 14.43 Cazul 6 de ştergere nod din arbore Roşu & Negru
B B
dezechilibru
P 22 P 22
dezechilibru interschimb culori (1) + rotire (2)
U
F F
4 69 4 N1 54
(1)
N2
U
N1
0 7 54 89 0 7 45 69
(2)
45 58 81 N2
58 89
81
Figura 14.44 Soluţie de reechilibrare caz 6 pentru arbore Roşu & Negru
P 22 P 22
dezechilibru
nod de şters
U U
F
15 69 4 69
F N1 N2 N1 N2
4 54 89 0 7 54 89
0 7 45 58 81 45 58 81
Figura 14.45 Cazul 7 de ştergere nod din arbore Roşu & Negru
B B
U P
F
4 69 22
(2) N2 89
(3)
N1 N2 F N1
0 7 54 89 4 54 81
45 58 81 0 7 45 58
Figura 14.46 Soluţie de reechilibrare caz 7 pentru arbore Roşu & Negru