1 Département Informatique
Département Informatique
Structures de données – partie 3
Arbres binaires de recherche algorithmes récursifs
Programmation objet
Cours n°7
Département Informatique Département Informatique
Les structures de données déjà étudiées (liste, tableau...) ne sont pas très efficaces pour la recherche par la valeur.
Si les recherches par valeur sont fréquentes, il est important de choisir une structure de données mémoire qui minimise le parcours.
Observons par exemple la recherche (par valeur) dans un tableau d'entiers trié.
3 Département Informatique
Département Informatique
Soit le tableau d'entiers suivant : 1 – 2 – 4 – 50 – 101 – 156 – 256 - 500
On désire faire une recherche dans ce tableau (de taille 8) pour savoir si 42 est présent ou non.
On procédera par une recherche dichotomique pour minimiser le nombre de tests.
On prend la moitié du tableau : V[4] = 101
101 est supérieur à 42, il est donc inutile de chercher après l'indice 4.
On prend la moitié du tableau restant : V[2]=4
4 est inférieur à 42, nous allons donc chercher au-dessus
E t a i n
Et ainsi de suite. Le nombre d'opérations nécessaire est très inférieur à 8
Département Informatique Département Informatique
L'idée serait d'avoir une structure qui soit forcément triée Il faut donc un critère de tri (ici c'était < )
Une des possibilités est la structure d'arbre binaire de recherche.
Le principe est simple : chaque « feuille » de l'arbre peut posséder deux « branches enfants » : une inférieure et une supérieure à elle.
Chaque recherche ne portera donc que sur la moitié des valeurs, à chaque itération, un peu comme dans un tableau trié.
5 Département Informatique
Département Informatique Exemple d'arbre binaire contenant des entiers.
10
50
75
1 15
90 60
54 100 Exemple : recherche de 23
-> non trouvé en 3 itérations
Exemple : recherche de 54 -> trouvé en 4 itérations Le nombre d'itérations maximum
est égal à la profondeur de l'arbre Pour n éléments, ce nombre
est log2(n)
Pour 10000 éléments, cela fait 13 itérations !
Département Informatique Département Informatique
Algorithme de recherche d'un entier Debut
fixe feuille courante à la racine tant que non trouvé
si feuille courante contient valeur cherchée trouvé <- vrai
sinon si valeur cherchée < valeur dans feuille courante
feuille courante <- branche gauche de feuille courante sinon
feuille courante <- branche droite de feuille courante fin si
fin tant que Fin
7 Département Informatique
Département Informatique Algorithme d'ajout d'un entier
Début Ajout
Fixe feuille courante à la racine de l'arbre Si feuille courante est vide
feuille courante <- nouvelle feuille
feuille courante prend la valeur à ajouter
sinon si valeur dans feuille courante < valeur à ajouter Prend branche gauche comme nouvelle racine Ajout
sinon si valeur dans feuille courante > valeur à ajouter Prend branche droite comme nouvelle racine Ajout
Fin si
Fin Ajout
Attention : algorithme récursif
Département Informatique Département Informatique
Exemple d'implémentation class arbre_entier
{
struct feuille {
int valeur;
feuille* gauche;
feuille* droite;
feuille(int v):valeur(v),gauche(NULL), droite(NULL){}
~feuille(){delete gauche; delete droite;}
};
feuille* racine;
arbre_entier():racine(NULL){}
~arbre_entier(){delete racine;}
9 Département Informatique
Département Informatique Méthode de recherche (non récursive)
bool trouve=false,fini=false;
feuille* feuille_courante = racine;
while(!fini) {
if(feuille_courante==NULL) fini=true;
else if(feuille_courante->valeur==i) { fini=true;
trouve=true; }
else if(feuille_courante->valeur < i) feuille_courante =
feuille_courante->gauche;
else feuille_c ourante =
feuille_courante->droite;
}
return trouve;
Département Informatique
Département Informatique Méthode d'ajout (récursive)
Nous utilisons une méthode récursive en passant la racine en paramètre void arbre_entier::ajoute(int val, feuille* &rac) {
if(rac==NULL)
rac=new feuille(val);
else if(rac->valeur < val)
ajoute(val,rac->gauche);
else if(rac->valeur > val)
ajoute(val,rac->droite);
}
On remarque qu'il ne se passe rien si la valeur est déjà présente dans l'arbre.
Paramètre de sortie
11 Département Informatique
Département Informatique Méthode d'envoi sur flux (récursive)
void arbre_entier::to_stream
(std::ostream& flux, pfeuille racine) {
if(racine) {
flux<<racine->valeur<<' ';
to_stream(flux,racine->gauche);
to_stream(flux,racine->droite);
} }
Comme pour l'ajout, l'algorithme le plus simple est récursif.
Département Informatique Département Informatique
Avantages
Recherche par la valeur rapide (log2(n))
Inconvénients
Ajout dans la collection peu rapide (comme recherche) Suppression d'un seul élément délicate (et longue)
Sur le dossier commun se trouve l'implémentation d'un arbre binaire de recherche d'entiers, ainsi qu'une collection générique.
13 Département Informatique
Département Informatique
Prochain cours :
Structures de données – partie 3bis arbres binaires de calcul
A la semaine prochaine !