Arbres binaires
Du fait de ce théorème, on ne considère dans un premier temps que le type arbre
binaire que l'on nommera arbreBinaire. Chaque sommet permet d'accéder
à deux sommets : le fils gauche et le fils droit.
Ce type sera nommé sommet. Chaque sommet
permet également d'accéder à l'objet qu'il stocke.
Un arbre binaire peut être vu comme un curseur indiquant le sommet
racine. De la même manière un sommet est un curseur.
On a donc
arbreBinaire=curseur;
sommet=curseur;
Le type sommet présente les primitives suivantes :
- accès
fonction getValeur(val S:sommet):objet;
/* vaut NULL si le sommet n'existe pas /*
fonction filsGauche(val S:sommet):sommet;
/* vaut NIL si S n'a pas de fils gauche */
fonction filsDroit(val S:sommet):sommet;
/* vaut NIL si S n'a pas de fils droit */
fonction pere(val S:sommet):sommet;
/* vaut NIL si S est la racine de l'arbre */
- modification
fonction setValeur(ref S:sommet;val x:objet):vide;
/* affecte au sommet S la valeur x */
fonction ajouterFilsGauche(ref S:sommet,val x:objet):vide;
/* filsGauche(S)==NIL doit être vérifié */
fonction ajouterFilsDroit(ref S:sommet,x:objet):vide;
/* filsDroit(S)==NIL doit être vérifié */
fonction supprimerFilsGauche(ref S:sommet):vide;
/* filsGauche(S) est une feuille */
fonction supprimerFilsDroit(ref S:sommet):vide;
/* filsDroit(S) est une feuille */
fonction detruireSommet(ref S:sommet):vide;
/* S est une feuille */
Il faut par ailleurs pouvoir créer la racine
d'un arbre on a donc de plus la primitive
fonction créerArbreBinaire(val Racine:objet):sommet;
et bien entendu détruire un arbre
fonction detruireArbreBinaire(ref A:arbreBinaire d'objet):vide;
Détection de feuille
fonction estFeuille(val S:sommet):booléen;
début
retourner(filsGauche(S)==NIL et filsDroit(S)==NIL)
fin
Construction d'un arbre binaire à partir d'un tableau d'entiers
On choisit de remplir l'arbre de haut en bas et de gauche à droite (parcours hiérarchique).
fonction remplirTableauArbre(ref T:tableau[1..N] d'entier):
arbreBinaire d'entier;
var A:arbreBinaire d'entier;
var F: file de sommet;
var s:sommet;
var i:entier;
début
créerFile(F);
A=créerArbreBinaire(T[1]);
enfiler(F,A);
tmp=2;
tantque 2*tmp-1<=N faire
pour i=tmp à 2*tmp-1 par pas de 2 faire
s=valeur(F);
defiler(F);
ajouterFilsGauche(s,T[i]);
enfiler(filsGauche(s));
ajouterFilsDroit(s,T[i+1]);
enfiler(filsDroit(s));
finpour;
tmp=tmp*2;
fintantque
pour i=tmp à N par pas de 2 faire
s=valeur(F);
defiler(F);
ajouterFilsGauche(s,T[i]);
ajouterFilsDroit(s,T[i+1]);
finpour;
si N mod 2 !=0 alors
ajouterFilsGauche(valeur(F),T[N])
finsi
detruireFile(F);
retourner(A);
fin
Parcours d'un arbre binaire
Le parcours d'un arbre binaire consiste à donner une liste de sommets
dans l'arbre.
Le prototype d'algorithme ci-dessous permet d'effectuer
les parcours suivant les algorithmes associés aux traitements à
partir d'un sommet de l'arbre.
fonction parcoursArbreBinaire(val A:arbreBinaire d'objet):vide;
// Déclarations locales
début
// traitement1;
si estFeuille(A)alors
// traitement2
sinon
// traitement3;
si filsGauche(A)!=NIL alors
// traitement4;
parcoursArbreBinaire(filsGauche(A));
// traitement5;
finsi
// traitement6;
si filsDroit(A)!=NIL alors
// traitement7
parcoursArbreBinaire(filsDroit(A));
// traitement8;
finsi
// traitement9;
finsi
// traitement1O;
fin
Complexité: si le traitementi a pour complexité
ci(n), soit
..
La complexité intrinsèque de
l'algorithme est O(n c(n)).
On distingue quatre parcours qui conditionnent les
algorithmes sur les arbres binaires.
Le parcours hiérarchique (voir paragraphe précédent) ainsi que les suivants :
- Parcours préfixe On liste la racine, les sommets du sous arbre gauche, puis les sommets du sous arbre droit.
- Parcours infixe On liste les sommets du sous arbre gauche, puis la racine puis les sommets du sous arbre droit.
- Parcours suffixe On liste les sommets du sous arbre gauche, puis les sommets du sous arbre droit puis la racine.
Exemple
- Parcours préfixe :7 5 9 8 4 6 2
- Parcours infixe : 9 5 8 7 6 2 4
- Parcours suffixe : 9 8 5 2 6 4 7
Affichage des valeurs des sommets pour un parcours donné
Soit un arbre étiquetté par des entiers. On considère que l'on dispose de la fonction suivante qui affiche un entier n sur le terminal
fonction afficher(val n:entier):vide;
- Affichage dans le parcours préfixe
pas de déclarations locales.
traitement 2, 3 : afficher(valeur(A));
- Affichage dans le parcours infixe
pas de déclarations locales.
traitement 2, 6: afficher(valeur(A));
- Parcours suffixe
pas de déclarations locales.
traitement 2, 9 : afficher(valeur(A));
Lister les étiquettes d'un arbre dans un tableau
fonction arbre2Tableau(val A:arbreBinaire d'entier;ref T:tableau[1..N] d'entier;ref i:entier):vide;
début
i=i+1;
T[i]=valeur(A);
si !estFeuille(A)alors
si filsGauche(A)!=NIL alors
arbre2Tableau(filsGauche(A),T,i);
finsi
si filsDroit(A)!=NIL alors
arbre2Tableau(filsDroit(A),T,i);
finsi
finsi
fin
Hauteur d'un arbre binaire
fonction hauteurArbreBinaire(val s:sommet):entier
début
si estFeuille(s)alors
retourner(0)
sinon
var tmp1,tmp2:entier;
tmp1=0;
tmp2=0;
si filsGauche(s)!=NIL alors
tmp1= hauteurArbreBinaire(filsGauche(s));
finsi
si filsDroit(s)!=NIL alors
tmp2=hauteurArbreBinaire(filsDroit(s));
finsi
retourner(1+max(tmp1,tmp2));
finsi
fin
Autre version
fonction hauteurArbreBinaireSimp(val s:sommet):entier
début
si s==NILalors
retourner(-1)
sinon
retourner(1+max(hauteurArbreBinaireSimp(filsGauche(s)),hauteurArbreBinaireSimp(filsDroit(s))));
finsi
fin
Remarque : La fonction hauteurArbreSimp (même si elle est plus
courte) a une complexité plus grande que la fonction
hauteurArbreBinaire notamment en nombre d'appel récursif. Elle
est moins performante.
Taille d'un sous-arbre d'un arbre binaire complet.
fonction tailleArbreBinaire(val A: arbreBinaire):entier;
var tmp:entier;
début
si estFeuille(A) alors
retourner(1)
sinon
retourner(1+tailleArbreBinaire(filsGauche(A))
+tailleArbreBinaire(filsDroit(A))
finsi
fin