Implémentation
L'intérêt du facteur d'équilibrage est que cette information nécessite 2 bits. Néammmoins les algorithmes permettant la gestion de eq sont délicats. Dans la suite, une cellule pour un arbre AVL doit contenir un champ supplémentaire qui
est la hauteur.
type celluleAVL=structure
info:objet;
hauteur:entier;
gauche:sommet;
droit:sommet;
père:sommet;
finstructure
sommetAVL=^celluleAVL;
On accède à ce nouveau champ par les deux primitives suivantes :
fonction getHauteur(ref S:sommet):entier;
/* 1 pour une feuille; 0 si NIL/*
fonction setHauteur(ref S:sommet; val h:sommet):entier;
/* 1 pour une feuille; 0 si NIL/*
Les fonctions implémentant les rotations sont immédiates.
fonction rotationDroite(ref y:sommet):vide;
var x,p:sommet;
début
x=filsGauche(y);
p=pere(y);
si p!=NIL alors
si y=filsGauche(p) alors
p^.gauche=x;
sinon
p^.droit=x;
finsi
finsi
x^.pere=p;
y^.pere=x;
y^.gauche=x^.droit;
x^.droit=y;
setHauteur(y,max(getHauteur(filGauche(y)),getHauteur(filsDroit(y)))+1);
setHauteur(x,max(getHauteur(filGauche(x)),getHauteur(filsDroit(x)))+1);
fin
fonction rotationGauche(ref x:sommet):vide;
var y,p:sommet;
début
y=filsDroit(x);
p=pere(x);
si p!=NIL alors
si x=filsGauche(p) alors
p^.gauche=y;
sinon
p^.droit=y;
finsi
finsi
y^.pere=p;
x^.pere=y;
x^.droit=y^.gauche;
y^.gauche=x;
setHauteur(x,max(getHauteur(filGauche(x)),getHauteur(filsDroit(x)))+1);
setHauteur(y,max(getHauteur(filGauche(y)),getHauteur(filsDroit(y)))+1);
fin
Les fonctions d'insertion et suppression doivent prendre en compte le calcul du
facteur d'équilibrage ainsi que le maintien de cet équilibre.
fonction ajouter(ref x:sommet, val e:objet):vide;
var s:sommet;
début
si e ≤ getValeur(x) alors
s=filsGauche(x);
si s==NIL alors
ajouterFilsGauche(x,e);
setHauteur(filsGauche(x),1)
equilibreAprèsInsertion(filsGauche(x))
sinon
ajouter(s,e);
finsi
sinon
s=filsDroit(x);
si s==NIL alors
ajouterFilsDroit(x,e);
setHauteur(filsDroit(x),1);
equilibreAprèsInsertion(filsDroit(x))
sinon
ajouter(s,e);
finsi
finsi
fin
fonction supprimer(ref x:sommet):booléen;
var p,f,y:sommet;
début
si estFeuille(x) alors
p=pere(x);
si filsGauche(p)==x alors
supprimerFilsGauche(p)
setHauteur(p,getHauteur(filsDroit(p)+1))
sinon
supprimerFilsDroit(p)
setHauteur(p,getHauteur(filsGauche(p)+1))
finsi
equilibreAprèsSuppression(p)
sinon
f=filsDroit(x);
si f!=NIL
y=cherchePlusPetit(f);
sinon
f=filsGauche(x);
y=cherchePlusGrand(f);
finsi
setValeur(x,getValeur(y));
supprimer(y);
finsi
fin
fonction equilibreAprèsInsertion(ref x:sommet,val cote:entier):vide;
var eq:entier;
var s,p:sommet;
début
eq=0;
p=x;
tantque pere(p)!=NIL et eq!=2 et eq!=2 faire
s=p;
p=pere(s);
setHauteur(p,max(getHauteur(filGauche(p)),getHauteur(filsDroit(p)))+1);
eq=getHauteur(filsDroit(p))-getHauteur(filsGauche(p));
fintantque
si eq==2 ou eq==-2 alors
equilibreUnSommet(p,s);
finsi
fin
Dans le cas de suppression, on remonte à partir de la feuille
supprimée dans l'arbre et de la même manière on détecte les noeuds
déséquilibrés.
Il est possible que plusieurs rotations soient nécessaires. En
effet un déséquilibre peut en entrainer un autre.
fonction equilibreAprèsSuppression(ref x:sommet):vide;
var eq:entier;
var s,p:sommet;
début
eq=1;
p=x;
p=pere(s);
tantque p!=NIL et eq!=0 faire
s=p;
p=pere(p);
setHauteur(p,max(getHauteur(filGauche(p)),getHauteur(filsDroit(p)))+1);
eq=getHauteur(filsDroit(p))-getHauteur(filsGauche(p));
equilibreUnSommet(p,s);
fintantque
fin
fonction equilibreUnSommet(ref p,s:sommet):vide;
début
si s==filsGauche(p) alors
si getEquilibre(p)==-2 alors
si getEquilibre(s)<1 alors
rotationDroite(p);
sinon
rotationGauche(s);
rotationDroite(p);
finsi
finsi
sinon
si getEquilibre(p)==2 alors
si getEquilibre(s)>-1 alors
rotationGauche(p)
sinon
rotationDroite(s);
rotationGauche(p);
finsi
finsi
finsi
fin