Vous êtes sur la page 1sur 2

VI.

Le minimum d’un arbre binaire


L’objectif est de rechercher la valeur minimale présente dans les nœuds d’un arbre binaire
quelconque.

A. Une première méthode


Décomposition
La valeur minimale dans un arbre est le minimum entre
- la valeur minimale dans le sous-arbre gauche,
- la valeur minimale dans le sous-arbre droit,
- la valeur de la racine.

Cette définition reste vraie même si l’un des sous-arbres est vide ou si les deux sous-arbres sont
vides, à condition de poser que la valeur minimale dans un arbre vide est +.

Cas de base
La valeur minimale dans un arbre vide est +.

En C++ on utilisera pour + la valeur maximale qui puisse être stockée dans un entier. Cette valeur
est donnée par la constante INT_MAX qui est définie dans le fichier entête climits.

// Renvoie le minimum du sous-arbre de racine r


int ArbreBinaire::minimum(Noeud *r) const
{
if (r == nullptr)
return INT_MAX;
else
return min( min(minimum(r->fg),minimum(r->fd)) , r->info );
}
La fonction min définie dans <algorithm> n’a que deux paramètres. On l’utilise donc deux fois pour
trouver le minimum parmi trois valeurs. Pour trouver le minimum entre deux entiers, la fonction min
effectue une comparaison entre ces deux entiers. Notre fonction effectue donc deux tests entre
entiers en chaque nœud de l’arbre. Sur un arbre de n nœuds, elle effectue 2n tests en tout. Ceci n’est
pas très efficace car pour rechercher le minimum dans un tableau de n éléments, n tests suffisent. La
raison pour laquelle notre fonction fait 2n tests est que la valeur de tous les nœuds qui n’ont pas de
fils gauche ou de fils droit est comparée inutilement à INT_MAX.

B. Une méthode plus efficace


La recherche du minimum dans un tableau peut être réalisée de la manière suivant :
- initialiser le minimum courant à +,
- parcourir le tableau et, pour chaque élément qui est plus petit que le minimum courant, remplacer
la valeur du minimum courant par la valeur de cet élément.

La même méthode peut être utilisée pour trouver le minimum dans un arbre : parcourir l’arbre et
comparer chaque nœud au minimum courant.

Dominique Schmitt L3 Informatique et Mathématiques 11


Comme nous l’avons vu dans les fonctions précédentes, pour parcourir un arbre il suffit de relancer
récursivement la fonction sur son sous-arbre gauche et sur son sous-arbre droit. Chaque appel
récursif va traiter un nœud de l’arbre en le comparant au minimum courant. Cela signifie que tous les
appels récursifs à la fonction doivent avoir accès à la même variable qui contient le minimum
courant. La seule manière (propre) de transmettre une variable d’une fonction à une autre, est de
passer cette variable en paramètre à la fonction. L’initialisation de la variable à + doit être faite
dans une fonction englobante, avant le premier appel à la fonction.

// Renvoie dans le paramètre m le minimum du sous-arbre de racine r.


// m est supposé initialisé à INT_MAX
void ArbreBinaire::minimum(Noeud *r, int &m) const
{
if (r != nullptr)
{
if (r->info < m)
{
m = r->info;
}
minimum(r->fg, m);
minimum(r->fd, m);
}
}

Notons que le paramètre m doit être passé par référence à la fonction puisqu’il est modifié par la
fonction.

Il est important de remarquer ici que le raisonnement qui a permis d’aboutir à cette fonction est un
raisonnement purement itératif : on parcourt l’arbre et on compare chaque nœud au minimum
courant. La fonction est cependant récursive puisque le parcours de l’arbre se fait par des appels
récursifs à la fonction. Cette manière de raisonner, sans donner de définition récursive du problème
à résoudre, est adaptée pour certaines fonctions mais doit être utilisée avec précaution.

Pour que la fonction minimum ci-dessus puisse être utilisée de manière plus naturelle dans un
programme, nous fournissons à l’utilisateur de la classe ArbreBinaire la fonction englobante
suivante :

// Renvoie le minimum de l’arbre auquel elle est appliquée


int ArbreBinaire::minimum() const
{
int m=INT_MAX;
minimum(racine,m);
return m;
}

Cette méthode est clairement plus efficace que la précédente puisqu’elle n’effectue qu’un seul test
entre entiers en chaque nœud.

Dominique Schmitt L3 Informatique et Mathématiques 12

Vous aimerez peut-être aussi