{
Arbres AVL
Réalisation D.E ZEGOUR
Insertion
Supression
Aout 2006
}
SOIT
Avl UN ARB DE ( ENTIER , ENTIER ) ;
{
// entier
1 : Valeur
// entier
2 : Balance
}
Tab UN VECTEUR (100 ) DE ENTIER ;
Inordre , Inserer , Supprimer DES ACTIONS ;
Balance UNE FONCTION ( ENTIERS ) ;
Aff_balance UNE ACTION ;
Equilibrer_ins , Equilibrer_sup
DES ACTIONS ;
Transf1 , Transf2 , Transf3 ,
Transf4 DES ACTIONS ;
Profondeur UNE FONCTION ( ENTIER ) ;
I UN ENTIER ;
DEBUT
Avl := NIL ;
POUR I := 1 , 100
AFF_ELEMENT ( Tab [ I ] , ALEANOMBRE ( 1000 ) ) ;
APPEL Inserer ( ELEMENT ( Tab [ I ] ) ) ;
APPEL
Inordre ( Avl ) }
FPOUR ;
ECRIRE ( 'Parcours Inordre' ) ;
APPEL Inordre ( Avl ) ;
ECRIRE ( 'suppression' ) ;
POUR I := 1 , 100
ECRIRE ( 'Sup de ' , ELEMENT ( Tab [ I ] ) ) ;
APPEL Supprimer ( ELEMENT ( Tab [ I ] ) ) ;
APPEL Inordre ( Avl ) ;
FPOUR ;
{ APPEL Inordre ( Avl ) ;}
FIN ;
FONCTION Balance ( P ) : ENTIER ;
SOIT
P UN ARB DE ( ENTIER , ENTIER ) ;
DEBUT
Balance := STRUCT ( INFO ( P ) , 2 )
FIN
ACTION Aff_balance ( P , V )
SOIT
P UN ARB DE ( ENTIER , ENTIER ) ;
V UN ENTIER ;
DEBUT
AFF_STRUCT ( INFO ( P ) , 2 , V )
FIN
FONCTION Profondeur ( P ) : ENTIER ;
SOIT
P UN ARB DE ( ENTIER , ENTIER ) ;
DEBUT
SI P = NIL
Profondeur
:= 0
SINON
Profondeur
:= MAX ( 1 + Profondeur ( FG ( P ) ) , 1 + Profondeur ( FD ( P ) ) )
FSI
FIN
ACTION Inordre ( P ) ;
SOIT
P UN ARB DE ( ENTIER , ENTIER ) ;
Tg , Td , Dif DES ENTIERS ;
DEBUT
SI P <> NIL
APPEL Inordre ( FG ( P ) ) ;
{ ECRIRE (
INFO ( P ) ) ;}
Tg :=
Profondeur ( FG ( P ) ) ;
Td :=
Profondeur ( FD ( P ) ) ;
SI Tg >= Td
Dif := Tg - Td
SINON
Dif := Td - Tg
FSI ;
SI Dif > 1
ECRIRE ( 'ERREUR
dif=' , Dif )
FSI ;
APPEL Inordre ( FD ( P ) )
FSI
FIN
ACTION Inserer ( Val )
SOIT
Val UN ENTIER ;
Doublet UN ( ENTIER , ENTIER ) ;
P , Q , R DES ARB DE ( ENTIER , ENTIER ) ;
Trouv UN BOOLEEN ;
Branche UNE PILE DE ARB DE ( ENTIER , ENTIER ) ;
DEBUT
ECRIRE ( 'inserer
>>>' , Val ) ;
CREERPILE ( Branche ) ;
SI Avl = NIL
INIT_STRUCT ( Doublet , [ Val , 0 ] ) ;
CREERNOEUD ( Avl ) ;
AFF_INFO ( Avl , Doublet )
SINON
P :=
Avl ;
Trouv
:= FAUX ;
TQ ( P <> NIL ) ET NON Trouv
SI STRUCT ( INFO ( P ) , 1 ) = Val
Trouv := VRAI
SINON
Q := P ;
EMPILER ( Branche , P ) ;
SI STRUCT ( INFO ( P ) , 1 ) > Val
P := FG ( P )
SINON
P := FD ( P )
FSI
FSI
FTQ ;
SI NON Trouv
INIT_STRUCT ( Doublet , [ Val , 0 ] ) ;
CREERNOEUD ( R ) ;
AFF_INFO ( R , Doublet ) ;
SI Val < STRUCT ( INFO ( Q ) , 1 )
AFF_FG ( Q , R )
SINON
AFF_FD ( Q , R )
FSI ;
APPEL Equilibrer_ins ( Branche , R ) ;
FSI ;
FSI
FIN
ACTION Equilibrer_ins ( Branche , R ) ;
SOIT
Branche UNE PILE DE ARB DE ( ENTIER , ENTIER ) ;
P , R , Parent DES ARB DE ( ENTIER , ENTIER ) ;
Arret UN BOOLEEN ;
DEBUT
Arret := FAUX ;
TQ NON PILEVIDE ( Branche ) ET ( NON Arret )
DEPILER ( Branche , P ) ;
SI FG ( P ) = R
APPEL Aff_balance ( P , Balance ( P ) + 1 )
SINON
APPEL Aff_balance ( P , Balance ( P ) - 1 )
FSI ;
SI ( Balance ( P ) = 2 ) OU ( Balance ( P ) = - 2 ) OU ( Balance ( P ) = 0 )
Arret := VRAI
SINON
R := P ;
FSI
FTQ ;
SI Arret
SI Balance ( P ) <> 0
SI PILEVIDE ( Branche )
Parent := NIL
SINON
DEPILER ( Branche , Parent )
FSI ;
SI Balance ( P ) = 2
APPEL Transf1 ( P , Parent )
SINON
APPEL Transf2 ( P , Parent )
FSI
FSI
FSI
FIN
ACTION Equilibrer_sup ( Branche , Sens ) ;
SOIT
Branche UNE PILE DE ARB DE ( ENTIER , ENTIER ) ;
P , R , Parent DES ARB DE ( ENTIER , ENTIER ) ;
Arret UN BOOLEEN ;
Sens UN ENTIER ;
Racine UN ARB DE ( ENTIER , ENTIER ) ;
Stop UN BOOLEEN ;
DEBUT
Arret
:= FAUX ;
DEPILER ( Branche , R ) ;
{ ECRIRE ( 'R:' , INFO ( R ) ) ;}
APPEL Aff_balance ( R , Balance ( R ) + Sens ) ;
SI PILEVIDE ( Branche )
Parent
:= NIL
SINON
DEPILER ( Branche , Parent ) ;
FSI ;
SI ( Balance ( R ) = 2 ) OU ( Balance ( R ) = - 2 )
SI Balance ( R ) = 2
APPEL Transf3 ( R , Parent , Racine ) ;
SINON
APPEL Transf4 ( R , Parent , Racine ) ;
FSI ;
R :=
Racine ;
{ECRIRE (
'Rapres:' , INFO ( R ) ) ;}
SINON
Arret
:= ( Balance ( R ) <> 0 )
FSI ;
TQ ( Parent <> NIL ) ET ( NON Arret )
P :=
Parent ;
{ECRIRE (
'P:' , INFO ( P ) ) ;}
SI ( FG ( P ) = R )
SI ( Balance ( R ) = 0 )
APPEL Aff_balance ( P , Balance ( P ) - 1 )
SINON
Arret := VRAI
FSI
SINON
SI ( Balance ( R ) = 0 )
APPEL Aff_balance ( P , Balance ( P ) + 1 )
SINON
Arret := VRAI
FSI
FSI ;
SI PILEVIDE ( Branche )
Parent := NIL
SINON
DEPILER ( Branche , Parent ) ;
FSI ;
SI ( Balance ( P ) = 2 ) OU ( Balance ( P ) = - 2 )
SI Balance ( P ) = 2
APPEL Transf3 ( P , Parent , Racine ) ;
SINON
APPEL Transf4 ( P , Parent , Racine ) ;
FSI ;
R := Racine
SINON
SI Balance ( P ) <> 0
Arret
:= VRAI
SINON
R := P ;
FSI
FSI
FTQ ;
FIN
ACTION Transf1 ( A , Parent ) ;
SOIT
A , B , C , Parent DES ARB DE ( ENTIER , ENTIER ) ;
DEBUT
ECRIRE ( 'transf1' ) ;
{A doit avoir un fils gauche}
B := FG ( A ) ;
SI Balance ( B ) = 1
{noeud inséré à gauche de B}
{Rotation droite}
ECRIRE ( 'Rotation droite
autour de ' , STRUCT ( INFO ( B ) , 1 ) ) ;
AFF_FG ( A , FD ( B ) ) ;
AFF_FD ( B , A ) ;
APPEL Aff_balance ( B , 0 ) ;
APPEL Aff_balance ( A , 0 ) ;
SI Parent = NIL
Avl := B
SINON
SI FG ( Parent ) = A
AFF_FG ( Parent , B )
SINON
AFF_FD ( Parent , B )
FSI
FSI
SINON
ECRIRE ( 'Rotation gauche
suivie par une rotation droite autour de '
, STRUCT ( INFO ( FD ( B ) ) , 1 ) ) ;
{ balance(b)
= -1 }
{noeud inséré
à droite de B}
{soit C le
fils droit de B (qui doit exister) }
C := FD ( B ) ;
{rotation
gauche}
AFF_FD ( B , FG ( C ) ) ;
AFF_FG ( C , B ) ;
{suivie par
une rotation droite}
AFF_FG ( A , FD ( C ) ) ;
AFF_FD ( C , A ) ;
{maj balance}
SI Balance ( C ) = 0
{ C est le
nouveau noeud inséré }
APPEL Aff_balance ( A , 0 ) ;
APPEL Aff_balance ( B , 0 ) ;
SINON
SI Balance ( C ) = 1
APPEL Aff_balance ( A , - 1 ) ;
APPEL Aff_balance ( B , 0 ) ;
APPEL Aff_balance ( C , 0
) ;
SINON
APPEL Aff_balance ( A , 0 ) ;
APPEL Aff_balance ( B , + 1 ) ;
APPEL Aff_balance ( C , 0 ) ;
FSI
FSI ;
SI Parent = NIL
Avl := C
SINON
SI FG ( Parent ) = A
AFF_FG ( Parent , C )
SINON
AFF_FD ( Parent , C )
FSI
FSI
FSI
FIN
ACTION Transf2 ( A , Parent ) ;
SOIT
A , B , C , Parent DES ARB DE ( ENTIER , ENTIER ) ;
DEBUT
ECRIRE ( 'transf2' ) ;
{A doit avoir un fils droit}
B := FD ( A ) ;
SI Balance ( B ) = - 1
ECRIRE ( 'Rotation gauche
autour de ' , STRUCT ( INFO ( B ) , 1 ) ) ;
{noeud inséré
à droite de B}
{Rotation
gauche}
AFF_FD ( A , FG ( B ) ) ;
AFF_FG ( B , A ) ;
APPEL Aff_balance ( B , 0 ) ;
APPEL Aff_balance ( A , 0 ) ;
SI Parent = NIL
Avl := B
SINON
SI FG ( Parent ) = A
AFF_FG ( Parent , B )
SINON
AFF_FD ( Parent , B )
FSI
FSI
SINON
ECRIRE ( 'Rotation droite
suivie par une rotation gauche autour de '
, STRUCT ( INFO ( FG ( B ) ) , 1 ) ) ;
{ balance(b)
= +1 }
{noeud inséré
à gauche de B}
{soit
C le fils gauche de B (qui doit exister) }
C := FG ( B ) ;
{rotation
gauche}
AFF_FG ( B , FD ( C ) ) ;
AFF_FD ( C , B ) ;
{suivie par
une rotation droite}
AFF_FD ( A , FG ( C ) ) ;
AFF_FG ( C , A ) ;
{maj balance}
SI Balance ( C ) = 0
{C est le
nouveau noeud inséré }
APPEL Aff_balance ( A , 0 ) ;
APPEL Aff_balance ( B , 0 ) ;
SINON
SI Balance ( C ) = 1
APPEL Aff_balance ( A , 0 ) ;
APPEL Aff_balance ( B , - 1 ) ;
APPEL Aff_balance ( C , 0 ) ;
SINON
APPEL Aff_balance ( A , + 1 ) ;
APPEL Aff_balance ( B , 0 ) ;
APPEL Aff_balance ( C , 0 ) ;
FSI
FSI ;
SI Parent = NIL
Avl := C
SINON
SI FG ( Parent ) = A
AFF_FG ( Parent , C )
SINON
AFF_FD ( Parent , C )
FSI
FSI
FSI
FIN
ACTION Transf3 ( A , Parent , Racine ) ;
SOIT
A , B , C , Parent , Racine DES ARB DE ( ENTIER , ENTIER ) ;
DEBUT
ECRIRE ( 'transf3' ) ;
{A doit avoir un fils gauche}
B := FG ( A ) ;
SI ( Balance ( B ) = 1 ) OU ( Balance ( B ) = 0 )
{Rotation droite}
ECRIRE ( 'Rotation droite
autour de ' , STRUCT ( INFO ( B ) , 1 ) ) ;
AFF_FG ( A , FD ( B ) ) ;
AFF_FD ( B , A ) ;
SI Balance ( B ) = 1
APPEL Aff_balance ( B , 0 ) ;
APPEL Aff_balance ( A , 0 ) ;
SINON
APPEL Aff_balance ( B , - 1 ) ;
APPEL Aff_balance ( A , 1 ) ;
FSI ;
Racine
:= B ;
SI Parent = NIL
Avl := B
SINON
SI FG ( Parent ) = A
AFF_FG ( Parent , B )
SINON
AFF_FD ( Parent , B )
FSI
FSI
SINON
ECRIRE ( 'Rotation gauche
suivie par une rotation droite autour de '
, STRUCT ( INFO ( FD ( B ) ) , 1 ) ) ;
{ balance(b)
= -1 }
{soit C le
fils droit de B (qui doit exister) }
C := FD ( B ) ;
{rotation
gauche}
AFF_FD ( B , FG ( C ) ) ;
AFF_FG ( C , B ) ;
{suivie par
une rotation droite}
AFF_FG ( A , FD ( C ) ) ;
AFF_FD ( C , A ) ;
{maj balance}
SI Balance ( C ) = 0
{ C est le
nouveau noeud inséré }
APPEL Aff_balance ( A , 0 ) ;
APPEL Aff_balance ( B , 0
) ;
SINON
SI Balance ( C ) = 1
APPEL Aff_balance ( A , - 1 ) ;
APPEL Aff_balance ( B , 0 ) ;
APPEL Aff_balance ( C , 0 ) ;
SINON
APPEL Aff_balance ( A , 0 ) ;
APPEL Aff_balance ( B , + 1 ) ;
APPEL Aff_balance ( C , 0 ) ;
FSI
FSI ;
Racine
:= C ;
SI Parent = NIL
Avl := C
SINON
SI FG ( Parent ) = A
AFF_FG ( Parent , C )
SINON
AFF_FD ( Parent , C )
FSI
FSI
FSI
FIN
ACTION Transf4 ( A , Parent , Racine ) ;
SOIT
A , B , C , Parent , Racine DES ARB DE ( ENTIER , ENTIER ) ;
DEBUT
ECRIRE ( 'transf4' ) ;
{A doit avoir un fils droit}
B := FD ( A ) ;
SI ( Balance ( B ) = - 1 ) OU ( Balance ( B ) = 0 )
ECRIRE ( 'Rotation gauche
autour de ' , STRUCT ( INFO ( B ) , 1 ) ) ;
{Rotation
gauche}
AFF_FD ( A , FG ( B ) ) ;
AFF_FG ( B , A ) ;
SI Balance ( B ) = - 1
APPEL Aff_balance ( B , 0
) ;
APPEL Aff_balance ( A , 0 ) ;
SINON
APPEL Aff_balance ( B , + 1 ) ;
APPEL Aff_balance ( A , - 1 ) ;
FSI ;
Racine
:= B ;
SI Parent = NIL
Avl := B
SINON
SI FG ( Parent ) = A
AFF_FG ( Parent , B )
SINON
AFF_FD ( Parent , B )
FSI
FSI
SINON
ECRIRE ( 'Rotation droite
suivie par une rotation gauche autour de '
, STRUCT ( INFO ( FG ( B ) ) , 1 ) ) ;
{ balance(b)
= +1 }
{soit C le
fils gauche de B (qui doit exister) }
C := FG ( B ) ;
{rotation
gauche}
AFF_FG ( B , FD ( C ) ) ;
AFF_FD ( C , B ) ;
{suivie par
une rotation droite}
AFF_FD ( A , FG ( C ) ) ;
AFF_FG ( C , A ) ;
{maj balance}
SI Balance ( C ) = 0
{C est le
nouveau noeud inséré }
APPEL Aff_balance ( A , 0 ) ;
APPEL Aff_balance ( B , 0 ) ;
SINON
SI Balance ( C ) = 1
APPEL Aff_balance ( A , 0 ) ;
APPEL Aff_balance ( B , - 1 ) ;
APPEL Aff_balance ( C , 0 ) ;
SINON
APPEL Aff_balance ( A , + 1 ) ;
APPEL Aff_balance ( B , 0 ) ;
APPEL Aff_balance ( C , 0
) ;
FSI
FSI ;
Racine
:= C ;
SI Parent = NIL
Avl := C
SINON
SI FG ( Parent ) = A
AFF_FG ( Parent , C )
SINON
AFF_FD ( Parent , C )
FSI
FSI
FSI
FIN
ACTION Supprimer ( Val )
SOIT
Val UN ENTIER ;
Sauv_balance UN ENTIER ;
P , Q , D DES ARB DE ( ENTIER , ENTIER ) ;
Trouv UN BOOLEEN ;
Branche UNE PILE DE ARB DE ( ENTIER , ENTIER ) ;
Sens UN ENTIER ;
DEBUT
CREERPILE ( Branche ) ;
P := Avl ;
Q := NIL ;
Trouv := FAUX ;
TQ ( P <> NIL ) ET NON Trouv
SI STRUCT ( INFO ( P ) , 1 ) = Val
Trouv := VRAI
SINON
Q := P ;
EMPILER ( Branche , P ) ;
SI STRUCT ( INFO ( P ) , 1 ) > Val
P := FG ( P ) ;
Sens := - 1
SINON
P := FD ( P ) ;
Sens := + 1
FSI
FSI
FTQ ;
SI Trouv
SI ( FG ( P ) = NIL ) ET ( FD ( P ) = NIL )
SI Q = NIL
Avl := Q ;
/* Bug : AVL:= NIL ne marche
pas!!! */
SINON
SI FG ( Q ) = P
AFF_FG ( Q , NIL )
SINON
AFF_FD ( Q , NIL )
FSI
FSI
SINON
SI FG ( P ) = NIL
SI Q = NIL
Avl := FD ( P )
SINON
SI FG ( Q ) = P
AFF_FG ( Q , FD ( P ) )
SINON
AFF_FD ( Q , FD ( P ) )
FSI
FSI
SINON
SI FD ( P ) = NIL
SI Q = NIL
Avl := FG ( P )
SINON
SI FG ( Q ) = P
AFF_FG ( Q , FG ( P ) )
SINON
AFF_FD ( Q , FG ( P ) )
FSI
FSI
SINON
D := FD ( P ) ;
Sens := + 1 ;
Q := P ;
EMPILER ( Branche , P ) ;
TQ FG ( D ) <> NIL
EMPILER ( Branche , D ) ;
Q := D ;
D := FG ( D ) ;
Sens := - 1
FTQ ;
{EMPILER ( Branche , D ) ;}
Sauv_balance := Balance ( P ) ;
AFF_INFO ( P , INFO ( D ) ) ;
APPEL Aff_balance ( P , Sauv_balance ) ;
SI FG ( Q ) = D
AFF_FG ( Q , FD ( D ) )
SINON
AFF_FD ( Q , FD ( D ) )
FSI
FSI
FSI
FSI ;
SI ( Q <> NIL )
APPEL Equilibrer_sup ( Branche , Sens )
FSI
FSI ;
FIN