You are on page 1of 18

Structuri de Date şi Algoritmi

Laborator V
Adrian Liţă
2015

1 Scopul laboratorului
Laboratorul V al materiei Structuri de Date şi Algoritmi are ca scop introducerea
structurilor de date arbore binar şi particularizări ale acestuia: arbore binar
de căutare şi arbore AVL.
În acest laborator se parcurg următoarele puncte:
• structura de date a unui arbore binar

• crearea din cod a unui arbore binar oarecare


• afişarea unui arbore folosind paranteze
• definirea arborelui binar de căutare
• inserarea nodurilor în arborele binar de căutare

• structura unui arbore AVL


• calculul înălţimii şi echilibrului unui nod al arborelui AVL
• echilibirarea unui arbore AVL

• inserarea nodurilor în arborele AVL

2 Desfăşurarea lucrării
În programare, arborii sunt structuri de date utile memorării eficiente a infor-
maţiei, în special pentru a manageria informaţiile memorate. Cele mai frecvente
utilizări ale arborilor sunt:
• managementul memoriei (în alocarea dinamică)
• managementul fişierelor (alocarea în directoare)
• baze de date

1
Un arbore binar reprezintă un arbore ce are doar doi descendenţi: unul în stânga
şi unul în dreapta. Structura unui arbore binar arată în felul următor:

Radacina

Subarbore Subarbore
Stang Drept

Figura 1: Arbore binar

1 t y p e d e f s t r u c t node
2 {
3 [ t i p de d a t e i n f o r m a t i e ]
4
5 s t r u c t node ∗ l e f t ;
6 s t r u c t node ∗ r i g h t ;
7 } NODE, ∗PNODE;

Nodul de sus se numeşte rădăcină, iar cei doi descendenţi ai săi se numesc
subarbore stâng şi subarbore drept. Dacă unul din descendenţi nu are niciun
descendent, atunci el se numeşte frunză.

2.1 Arbore binar oarecare


Pentru a crea un arbore binar oarecare nu există o metodă consacrată, aşa că
vom crea arborele din figura 2 plecând de la frunze până la rădăcină: crearea
fiecărei frunze în parte, după care fiecare părinte al frunzelor, etc.

2
1

2 3

NULL NULL NULL


4

NULL NULL

Figura 2: Arbore binar oarecare

1 t y p e d e f s t r u c t node
2 {
3 int info ;
4 s t r u c t node ∗ l e f t ;
5 s t r u c t node ∗ r i g h t ;
6 } NODE, ∗PNODE;
7
8
9 // f u n c t i a c e c r e e a z a un a r b o r e . p r i m e s t e i n f o r m a t i a pe c a r e o t i n e
r a d a c i n a , s i c e i 2 sub−a r b o r i
10 PNODE makeTree ( i n t i nf o _r a d , PNODE l e f t L e a f , PNODE r i g h t L e a f )
11 {
12 PNODE e = (PNODE) m a l l o c ( s i z e o f (NODE) ) ;
13 i f ( e == NULL)
14 {
15 p r i n t f ( " E r o a r e l a a l o c a r e ! \ n" ) ;
16 exit (0) ; // nu a r e s e n s s a c o n t i n u i
17 }
18 e−>i n f o = i n f o _ r a d ;

3
19 e−> l e f t = l e f t L e a f ;
20 e−>r i g h t = r i g h t L e a f ;
21
22 return e ;
23 }
24
25 i n t main ( )
26 {
27
28 // d e c l a r a m a r b o r i i . f i e c a r e e l e m e n t d i n a r b o r e e s t e un sub−a r b o r e
,
29 // d e c i un a r b o r e l a r a n d u l l u i nu e s t e n e v o i e s a mai i n i t i a l i z a m
cu NULL.
30 // daca va u i t a t i l a f u n c t i a makeTree , a c e a s t a nu s e u i t a l a
pointer efectiv .
31 PNODE rad1 , rad2 , rad3 , rad4 ;
32
33 // i n t a i creem f r u n z e l e
34 rad4 = makeTree ( 4 , NULL, NULL) ;
35 rad2 = makeTree ( 2 , NULL, NULL) ;
36
37 // a p o i s u b a r b o r e l e d r e p t
38 rad3 = makeTree ( 3 , rad4 , NULL) ;
39
40 // s i r a d a c i n a mare
41 rad1 = makeTree ( 1 , rad2 , rad3 ) ;
42
43 system ( " pause " ) ;
44 return 0;
45 }

2.2 Afişarea unui arbore


Afişarea unui arbore se poate face în mai multe feluri, cea mai exemplifica-
tivă fiind desenarea (grafică) a acestuia (precum figura 2). Totuşi, acest lucru
este destul de dificil de realizat în practică, în special dintr-o aplicaţie de con-
solă. În consolă, cea mai simplă formă de a afişa un arbore este prin paranteze.

Acest lucru se face foarte uşor. Arborele binar din figura 1 se reprezintă
prin paranteze astfel: rădăcină(subarbore stâng, subarbore drept). Mai
exact, arborele din figura 2 reprezentat prin paranteze arată în felul următor:
1(2,3(4,N)). Codul care realizează această funcţie este prezentat mai jos:
1 v o i d a f i s a r e _ c u _ p a r a n t e z e (PNODE rad )
2 {
3 i f ( rad == NULL)
4 {
5 p r i n t f ( "N" ) ;
6 return ;
7 }
8
9 p r i n t f ( "%d" , rad−>i n f o ) ;
10
11 i f ( ( rad−> l e f t ) | | ( rad−>r i g h t ) )

4
12 {
13 printf ("(") ;
14 a f i s a r e _ c u _ p a r a n t e z e ( rad−> l e f t ) ;
15 printf (" ,") ;
16 a f i s a r e _ c u _ p a r a n t e z e ( rad−>r i g h t ) ;
17 printf (")") ;
18 }
19 }

Funcţia afisare_cu _paranteze() este o funcţie recursivă care odată apelată


pentru o rădăcină, afişează informaţia din aceasta, după care, dacă acestă ră-
dăcină nu este frunză, se auto-apelează pentru ambii descendenţi ai rădăcinei.
Dacă rădăcina nu are decât un descendent, în momentul apelării funcţiei pentru
descendentul inexistent, funcţia va afişa N (de la NULL).

2.3 Arborele binar de căutare


Un arbore binar de căutare este un arbore binar cu următoarea proprietate:
rădăcina este mai mare decât descendentul stâng, şi mai mică decât descendentul
drept:
stanga < rad (1)
rad < dreapta (2)
Proprietăţile arborelui binar de căutare sunt următoarele:
• subarborele stâng este mai mic decât rădăcina, care este mai mică decât
subarborele drept
• cea mai din stânga frunză este cel mai mic element al arborelui

• cea mai din dreapta frunză este cel mai mare element al arborelui
• toti subarborii arborelui binar de căutare sunt arbori binari de căutare
• orice operaţie efectuată asupra unui arbore binar de căutare (adăugare,
ştergere noduri) trebuie să-l menţină arbore binar de căutare

5
X

S<X D>X

Figura 3: Arbore binar de căutare

2.4 Adăugarea unui nod în arborele binar de căutare


Într-un arbore binar de căutare, un nod nu se poate adăuga oriunde, ci trebuie
să respecte regula arborelui binar de căutare: dacă este mai mic decât rădă-
cina, va fi plasat în stânga. Dacă este mai mare decât rădăcina, va fi plasat
în dreapta. Acest lucru este valabil pentru fiecare rădăcină şi sub-rădăcină în
parte. Inevitabil, un nod nou-adăugat într-un arbore binar de căutare va fi în-
totdeauna o frunză.

Algorimul de implementare a adăugarii unui nod într-un arbore binar de că-


utare este următorul:
1. Se porneşte de la rădăcina arborelui. Dacă arborele este gol, noul nod va
deveni rădăcina arborelui.

2. Se compară informaţia ce trebuie adăugată cu rădăcina. Dacă informaţia


nouă este mai mică, se caută în subarborele stâng, iar în caz contrar
(informaţia nouă este mai mare) se caută în subarborele drept.
3. Se parcurg paşii 1-2 până când se ajunge la o frunză a arborelui existent.

4. Frunza la care se ajunge în final va deveni rădăcină pentru un nou sub-


arbore. Respectând proprietăţile arborelui binar de căutare, noul nod se
adaugă ca descendent al acestei noi rădăcini: fie în stânga (dacă este mai
mic) fie în dreapta (dacă este mai mare).
Algoritmul este exemplificat în cod în liniile ce urmează:

6
1 t y p e d e f s t r u c t node
2 {
3 int info ;
4 s t r u c t node ∗ l e f t ;
5 s t r u c t node ∗ r i g h t ;
6 } NODE, ∗PNODE;
7
8 PNODE i n s e r a r e (PNODE rad , i n t info_new )
9 {
10 // alocam s p a t i u p e n t r u n o u l nod
11 PNODE e = (PNODE) m a l l o c ( s i z e o f (NODE) ) ;
12 i f ( e == NULL)
13 {
14 p r i n t f ( " E r o a r e l a a l o c a r e ! \ n" ) ;
15 exit (0) ; // nu a r e s e n s s a c o n t i n u i
16 }
17 e−>i n f o = info_new ;
18 e−> l e f t = NULL;
19 e−>r i g h t = NULL;
20
21
22 // v e r i f i c a m s i c a z u l cand a r b o r e l e e s t e g o l
23 i f ( rad == NULL)
24 return e ;
25
26 // s e p a r c u r g e a r b o r e l e pana l a f r u n z a c a r e va d e v e n i r a d a c i n a
27 PNODE f r u n z a = rad ;
28 PNODE i = rad ;
29 while ( i )
30 {
31 frunza = i ;
32 i f ( info_new < i −>i n f o )
33 i = i −> l e f t ;
34 else
35 i = i −>r i g h t ;
36 }
37
38 // i n a c e s t moment p o i n t e r u l f r u n z a a r e a d r e s a n o i i sub−r a d a c i n e
39 i f ( info_new < f r u n z a −>i n f o )
40 f r u n z a −> l e f t = e ;
41 else
42 f r u n z a −>r i g h t = e ;
43
44 r e t u r n rad ;
45 }
46
47 v o i d a f i s a r e _ c u _ p a r a n t e z e (PNODE rad )
48 {
49 ...
50 }
51
52 i n t main ( )
53 {
54 PNODE rad = NULL; // plecam de l a un a r b o r e g o l
55 rad = i n s e r a r e ( rad , 4 ) ;
56 rad = i n s e r a r e ( rad , 5 ) ;
57 rad = i n s e r a r e ( rad , 6 ) ;

7
58 rad = i n s e r a r e ( rad , −4) ;
59 rad = i n s e r a r e ( rad , −5) ;
60 rad = i n s e r a r e ( rad , −6) ;
61 rad = i n s e r a r e ( rad , −1) ;
62 rad = i n s e r a r e ( rad , −2) ;
63 rad = i n s e r a r e ( rad , −3) ;
64 rad = i n s e r a r e ( rad , 1) ;
65 rad = i n s e r a r e ( rad , 2) ;
66 rad = i n s e r a r e ( rad , 3) ;
67
68 a f i s a r e _ c u _ p a r a n t e z e ( rad ) ;
69
70 system ( " pause " ) ;
71 return 0;
72 }

Arborele rezultat în urma rulării codului de mai sus, reprezentat prin paranteze
este: 4(-4(-5(-6,N),-1(-2(-3,N),1(N,2(N,3)))),5(N,6)) şi poate fi vizualizat grafic
în figura 4

-4 5

-5 -1 6

-6 -2 1

-3 2

Figura 4: Exemplu arbore binar de căutare

Notă. Într-un arbore binar de căutare contează ordinea introducerii informaţiei.


În arborele din figura 4 nodurile au fost inserate în următoarea ordine: 4,5,6,-
4,-5,-6,-1,-2,-3,1,2,3. Observaţi că primul nod introdus a rămas întotdeauna

8
rădăcină. Acest lucru nu va mai fi valabil într-un arbore AVL (capitolul 2.5).
De asemenea, dacă introduceam nodurile în altă ordine, arborele arăta într-o cu
totul altă formă (deşi era tot arbore binar de căutare şi respecta proprietăţile
acestuia).

2.5 Structura unui arbore AVL


Structura unui arbore AVL este similară cu cea a unui arbore binar de căutare,
având în plus încă un câmp de date ce memorează echilibrul nodului.
1 t y p e d e f s t r u c t node
2 {
3 [ t i p de d a t e i n f o r m a t i e ]
4 int balance ;
5 s t r u c t node ∗ l e f t ;
6 s t r u c t node ∗ r i g h t ;
7 } NODE, ∗PNODE;

Proprietăţile arborelui AVL, sunt următoarele:


• toate proprietăţile arborelui binar de căutare

• numărul maxim de paşi în căutarea a unui nod este H(rad)


• numărul mediu de paşi în căutarea unui nod se află între H(rad) şi H(rad-
1)
• înălţimea arborelui este apropiată de log2 (nrtotaldenoduri)

Arborele AVL reprezintă un caz aparte de arbore binar de căutare, mai exact
este un arbore binar de căutare echilibrat. Acest lucru înseamnă că fiecare
nod trebuie să respecte, pe lângă proprietăţile arborelui binar de căutare şi
următoarea inecuaţie:
|E(x)| < 2 (3)
unde E(x) reprezintă echilibrul nodului x, şi este dat de ecuaţia:

E(rad) = H(subarboredrept) − H(subarborestang) (4)

unde H(x) reprezintă înălţimea nodului x, şi este definită ca distanţa maximă


de la nodul x până la frunze. Codul aferent calculului înălţimii este următorul:
1 i n t i n a l t i m e (PNODE rad )
2 {
3 i f ( ! rad )
4 r e t u r n 0 ; // a r b o r e g o l
5
6 // c a l c u l e z i n a l t i m e a c o p i i l o r
7 i n t i n a l t i m e L e f t = i n a l t i m e ( rad−> l e f t ) ;
8 i n t i n a l t i m e R i g h t = i n a l t i m e ( rad−>r i g h t ) ;
9
10 // pe c a r e e mai mare . . pe a i a o r e t u r n e z .
11 // p l u s 1 p e n t r u ca pun s i nodul c u r e n t l a s o c o t e a l a
12 i f ( inaltimeLeft > inaltimeRight )

9
13 r e t u r n i n a l t i m e L e f t +1;
14 else
15 r e t u r n i n a l t i m e R i g h t +1;
16 }

Codul aferent calculului echilibrului unui nod (bazat pe ecuaţia 1), precum şi a
calculului echilibrului întregului arbore (bazat pe funcţia de calcul al echilibrului
unui singur nod) este următorul:
1 v o i d c a l c u l _ e c h i l i b r u _ n o d (PNODE x )
2 {
3 x−>b a l a n c e = i n a l t i m e ( x−>r i g h t ) − i n a l t i m e ( x−> l e f t ) ;
4 }
5
6 v o i d c a l c u l _ e c h i l i b r u _ a r b o r e (PNODE rad )
7 {
8 // c a l c u l e a z a e c h i l i b r u l i n t r e g u l u i a r b o r e
9 // ( a d i c a s e t e a z a b a l a n c e p e n t r u f i e c a r e e l e m e n t i n p a r t e )
10 i f ( ! rad )
11 return ;
12
13 c a l c u l _ e c h i l i b r u _ a r b o r e ( rad−>r i g h t ) ;
14 c a l c u l _ e c h i l i b r u _ a r b o r e ( rad−> l e f t ) ;
15
16 c a l c u l _ e c h i l i b r u _ n o d ( rad ) ;
17 }

Un arbore AVL perfect este un arbore AVL în care toate nodurile au echilibrul
0. Un astfel de exemplu este prezentat în figura 5.

4 12

2 6 10 14

1 3 5 7 9 11 13 15

Figura 5: Arbore AVL perfect

2.6 Echilibrarea unui arbore AVL


În timpul inserării nodurilor sau a ştergerii acestora, arborele AVL se poate deze-
chilibra (practic nu va mai fi arbore AVL). Acest lucru va strica proprietăţile
în materie de timp de acces şi eficienţă al arborelui (practic nu mai garantează

10
nimic că pot gasi un nod într-un timp maxim dat). Pentru a redeveni arbore
AVL, acesta trebuie echilibrat. Operaţiunea de echilibrare se execută pentru
fiecare nod dezechilibrat vizat şi presupune rotiri ale nodurilor.

Algoritmul de echilibrare al unui nod din arborele AVL este următorul:


1. Se calculează echilibrul curent al nodului după formula din ecuaţia .
2. Dacă echilibrul este egal cu -2 înseamnă că nodul este dezechilibrat prin
descendentul stâng. Evident, echilibrul descendentului stâng nu poate fi
decât 0 sau 1.
• Dacă echilibrul descendenului stâng este 0, se va executa o rotire
simplă la dreapta asupra nodului.
• Dacă echilibrul descendenului stâng este 1, se va executa o rotire
dublă la dreapta asupra nodului.
3. Dacă echilibrul este egal cu 2 înseamnă că nodul este dezechilibrat prin
descendentul drept. Evident, echilibrul descendentului drept nu poate fi
decât 0 sau -1.
• Dacă echilibrul descendenului stâng este 0, se va executa o rotire
simplă la stânga asupra nodului.
• Dacă echilibrul descendenului stâng este -1, se va executa o rotire
dublă la stânga asupra nodului.
Rotirile simple sunt compuse din interschimbări între rădăcină şi descendenţi:
• rotirea simplă la stânga:
1. descendentul din stânga va fi mutat în dreapta
2. în stanga fostului descendent din dreapta va fi mutată rădăcina (evi-
dent pentru că rădăcina este mai mică decât descendentul ei din
dreapta)
3. noua rădăcina va fi fostul descendent din dreapta
• rotirea simplă la dreapta:
1. descendentul din dreapta va fi mutat în stânga
2. în dreapta fostului descendent din stânga va fi mutată rădăcina (evi-
dent pentru că rădăcina este mai mare decât descendentul ei din
stânga)
3. noua rădăcina va fi fostul descendent din stânga
Rotirile duble sunt alcătuite din două rotiri simple
• rotirea dublă la stânga:
1. se aplică o rotire simplă la dreapta descendentului drept

11
2. se aplică o rotire simplă la stânga asupra rădăcinei
• rotirea dublă la dreapta:
1. se aplică o rotire simplă la stânga descendentului stâng
2. se aplică o rotire simplă la dreapta asupra rădăcinei

Codul aferent rotirilor şi echilibrării unui nod:


1 // r o t i r e s i m p l a s t a n g a
2 PNODE s R o t i r e S t a n g a (PNODE rad )
3 {
4 PNODE temp ;
5 temp = rad−>r i g h t ;
6 rad−>r i g h t = temp−> l e f t ;
7 temp−> l e f t = rad ;
8 rad = temp ;
9 r e t u r n rad ;
10 }
11
12 // r o t i r e s i m p l a d r e a p t a
13 PNODE s R o t i r e D r e a p t a (PNODE rad )
14 {
15 PNODE temp ;
16 temp = rad−> l e f t ;
17 rad−> l e f t = temp−>r i g h t ;
18 temp−>r i g h t = rad ;
19 rad = temp ;
20 r e t u r n rad ;
21 }
22
23 // r o t i r e dubla r i g h t − l e f t
24 PNODE d R o t i r e S t a n g a (PNODE rad )
25 {
26 rad−>r i g h t = s R o t i r e D r e a p t a ( rad−>r i g h t ) ;
27 rad = s R o t i r e S t a n g a ( rad ) ;
28 r e t u r n rad ;
29 }
30
31 // r o t i r e dubla l e f t −r i g h t
32 PNODE d R o t i r e D r e a p t a (PNODE rad )
33 {
34 rad−> l e f t = s R o t i r e S t a n g a ( rad−> l e f t ) ;
35 rad = s R o t i r e D r e a p t a ( rad ) ;
36 r e t u r n rad ;
37 }
38
39 PNODE e c h i l i b r a r e (PNODE rad )
40 {
41 PNODE temp ;
42 c a l c u l _ e c h i l i b r u _ n o d ( rad ) ;
43
44 i f ( rad−>b a l a n c e == −2)
45 {
46 temp = rad−> l e f t ;
47 i f ( temp−>b a l a n c e == 1 )
48 rad = d R o t i r e D r e a p t a ( rad ) ;

12
49 else
50 rad = s R o t i r e D r e a p t a ( rad ) ;
51 }
52 else
53 i f ( rad−>b a l a n c e == 2 )
54 {
55 temp = rad−>r i g h t ;
56 i f ( temp−>b a l a n c e == −1)
57 rad = d R o t i r e S t a n g a ( rad ) ;
58 else
59 rad = s R o t i r e S t a n g a ( rad ) ;
60 }
61 r e t u r n rad ;
62 }

2.7 Inserarea unui nod din arborele AVL


Inserarea unui nod într-un arbore AVL se face similar cu inserarea unui nod într-
un arbore binar de căutare, cu adăugirea că după inserare, pornind de la frunză
spre rădăcină, se calculează echilibrul fiecărui nod parcurs pentru a insera, şi
dacă modulul acestuia este 2, atunci se echilibrează nodul. Codul recurisv de
inserare a nodului în arborele AVL este următorul:
1 PNODE inserareAVL (PNODE rad , i n t info_new )
2 {
3 i f ( ! rad )
4 {
5 // alocam s p a t i u p e n t r u n o u l nod
6 PNODE e = (PNODE) m a l l o c ( s i z e o f (NODE) ) ;
7 i f ( e == NULL)
8 {
9 p r i n t f ( " E r o a r e l a a l o c a r e ! \ n" ) ;
10 exit (0) ; // nu a r e s e n s s a c o n t i n u i
11 }
12
13 e−>i n f o = info_new ;
14 e−>b a l a n c e = 0 ;
15 e−> l e f t = NULL;
16 e−>r i g h t = NULL;
17 return e ;
18 }
19
20 i f ( info_new < rad−>i n f o )
21 rad−> l e f t = inserareAVL ( rad−>l e f t , info_new ) ;
22 else
23 i f ( info_new > rad−>i n f o )
24 rad−>r i g h t = inserareAVL ( rad−>r i g h t , info_new ) ;
25 else
26 p r i n t f ( " I n f o r m a t i a d e j a e x i s t a \n" ) ;
27
28 rad = e c h i l i b r a r e ( rad ) ;
29 r e t u r n rad ;
30 }

Rotirile, echilibrarea şi inserarea nodurilor sunt exemplificate în imagini în anexa


de la sfârşitul lucrării.

13
3 Probleme
1. Implementaţi o funcţie care creează un arbore binar de căutare dintr-un
vector dat.

2. Implementaţi o funcţie care numără toate nodurile unui arbore.


3. Implementaţi o funcţie care primeşte ca parametru rădăcina arborelui şi
care şterge toate nodurile acestuia (descendenţii plus rădăcina).
4. Implementaţi o funcţie care creează un arbore AVL dintr-un vector dat.

5. Implementaţi varianta nerecursivă a funcţiei de ştergere a unui singur nod


din arborele binar de căutare.
6. Implementaţi o funcţie care şterge minimul şi maximul dintr-un arbore
AVL.

7. Implementaţi o bază de date de persoane. Căutaţi apoi persoane în acea


bază de date.

14
CS216 Fall 2001

AVL Trees Example

Insert 3 Insert 2 Insert 1 (non-AVL) AVL

3 3 3 2

2 2 Single 1 3
rotation
1

Insert 4 Insert 5 (non-AVL) AVL

2
2 2

Single 1 4
3 1 3
1 rotation

3 5
4 4

Insert 6 (non-AVL) AVL Insert 7 (non-AVL)

4 4
2

Single 2 5 2 5
1 4 rotation

1 3 6 1 3 6
3 5

7
6

9/27/01 Page 1 of 4
CS216 Fall 2001

AVL Insert 16 Insert 15 (non-AVL)

4
4 4
Single
rotation 2 6
2 6 2 6

1 3 5 7
1 3 5 7 1 3 5 7

16 16

15

Step 1: Rotate child and grandchild Step 2: Rotate node and new child (AVL)

4 4

Double 2 6 2 6
rotation

1 3 5 7 1 3 5 15

15 7 16

16

Insert 14 (non-AVL) Step 1: Rotate child and Step 2: Rotate node and
grandchild new child (AVL)

4
4 4
Double
rotation 2 7
2 6 2 6

1 3 6 15
1 3 5 15 1 3 5 7

16
7 16 15 5 14

14 14 16

9/27/01 Page 2 of 4
CS216 Fall 2001

AVL Tree No longer AVL, must rebalance

Insert a node

h h +1 h h +2

Two ways to expand subtree of height h+2:

h h

h h +1 h +1 h
h +2
h +2
Apply a Single Rotation Apply a Double Rotation

Note: the symmetrical case is handled


identically (i.e. mirror image)

9/27/01 Page 3 of 4
CS216 Fall 2001

Single Rotation:

B D

Single
rotation
D B

A
E

h h +1
C E A C

h h +1 h h

h +2
Double Rotation:

B
D

F
B F
A Double
rotation
D
h

G A C E G

h h h h -1 h
C E OR
h-1 h
h h -1 OR
h h
OR
h-1 h
OR
h h
h +1

h +2
9/27/01 Page 4 of 4

You might also like