arbre binaire

Download Report

Transcript arbre binaire

Arbres binaires et tables de
hachage
Introduction

Les arborescences sont utilisées :


Dans la vie de tous les jours : pour représenter
des hiérarchies, des classifications, des partitions
Dans le domaine de l'informatique : pour
représenter les informations ci-dessus, et
aussi :



L'organisation interne des fichiers en mémoire
Les mode de calcul d'une expression
L'organisation de données triées
Introduction

Exemple
Introduction

Utilisations




Système de fichier
Parsing de texte (compilation, XML, …)
Base de données (indexation)
Intelligence artificielle (arbres de décision)
Définition

Un arbre est une collection (finie) de noeuds
de même type

Un arbre est défini (récursivement) par :


un premier noeud (racine de l’arbre)
0, 1, 2 ou plusieurs sous-arbres (appelés
descendants de la racine)
Vocabulaire
Définition

L’arité d’un nœud est le nombre de fils de ce
nœud




Binaire: 2 fils
Ternaire: 3 fils
N-aire …
Un arbre binaire est un arbre dans lequel
chaque noeud possède 0, 1 ou 2 fils

Chaque noeud a un descendant gauche et un
descendant droit (éventuellement vides)
Définition
Les arbres binaires

1 élément = 3 parties (agrégat)



Le champ donnée
Le fils gauche (sous-arbre)
Le fils droit (sous-arbre)
Donnée
Gauche
Droite
Les arbres binaires

Déclaration de la structure d’un arbre binaire
typedef struct s_btree {
void
*donnee;
struct s_btree *gauche;
struct s_btree *droite;
} t_btree;
Les opérations de base

Création d’un nouvel arbre
t_btree*btree_new_root(void *donnee, t_btree *gauche,
t_btree *droite)
{
t_btree
*nouvel_arbre;
nouvel_arbre = malloc(sizeof (t_btree));
nouvel_arbre->droite = droite;
nouvel_arbre->gauche = gauche;
nouvel_arbre->donnee = donnee;
return (nouvel_arbre);
}
Les opérations de base

Les parcours en profondeur
Les opérations de base

Affichage ordre Préfixe
void btree_prefixe(t_btree *arbre, void (*f)(void *))
{
if (arbre == NULL)
return ;
else
{
f(arbre->donne);
btree_apply(arbre->gauche, f);
btree_apply(arbre->droite, f);
}
}
Les opérations de base

Affichage ordre Infixe (symétrique)
void btree_infixe(t_btree *arbre, void (*f)(void *))
{
if (arbre == NULL)
return ;
else
{
btree_apply(arbre->gauche, f);
f(arbre->donne);
btree_apply(arbre->droite, f);
}
}
Les opérations de base

Affichage ordre suffixe (postfixe)
void btree_suffixe(t_btree *arbre, void (*f)(void *))
{
if (arbre == NULL)
return ;
else
{
btree_apply(arbre->gauche, f);
btree_apply(arbre->droite, f);
f(arbre->donne);
}
}
Les opérations de base

Parcours en largeur (hiérarchique)
Exercice
Exercice
Parcours préfixe:
ABCEIFJDGHKL
 Parcours Infixe:
E I C F J B G D K H LA
 Parcours suffixe:
IEJFCGKLHDBA
 Parcours en largeur:
ABCDEFGHIJKL

Les arbres binaires de recherche (ABR)

Un arbre binaire de recherche est un arbre
binaire dans lequel la valeur de chaque
sommet est


supérieure [ou égale] à toutes les valeurs
étiquetant les sommets du sous-arbre gauche de
ce sommet,
et inférieure à toutes les valeurs étiquetant les
sommets du sous-arbre droit de ce sommet.
Les arbres binaires de recherche (ABR)
Algorithme de construction

Soit val la valeur à placer dans l’ABR (l’ajout se fera
toujours sur une «feuille» : arbre binaire dont le Fils G et
le Fils D sont vides)



Si l’arbre est vide, en créer un, réduit à sa racine, étiquetée avec
val
Sinon si val ≤ valeur portée par la racine, alors l’ajouter au sousarbre gauche : si cet arbre n’est pas vide, reprendre l’algorithme
sur ce sous-arbre
Sinon l’ajouter au sous-arbre droit : si cet arbre n’est pas vide,
reprendre l’algorithme sur ce sous-arbre
Avantages des ABR

Faible complexité pour la recherche

O(n) pour trouver une valeur où n représente
la profondeur de l’arbre
Tables de hachages
Définition

Ensemble de données de la forme (k, v)



L’objectif est de retrouver v en fournissant k:


K est appelé la clé
V est une valeur associée à k
On peut voir une table T comme une fonction d’un ensemble de
clés k vers un ensemble de valeur v
Exemple:


K = ensemble des départements
V = ensemble des préfectures
La fonction de hachage
Les collisions

L’inconvénient de cette idée est que deux clés peuvent
être hachées dans la même case de la table : collision.

Exemple : si les clés sont des valeurs numériques, on
peut considérer la fonction de hachage simple suivante :
H(k) = k mod m
Pour m = 10000 on a :
H(4325678) = h(35678) = 5678
Résolution des collisions
Choix de la fonction de hachage

L’hypothèse «hachage uniforme simple» est
difficile à garantir, mais il existe des
techniques qui fonctionnent bien en pratique.

Une bonne fonction de hachage doit
distribuer les clés uniformément dans les
cases de la table.
La fonction modulo

On suppose que toutes les clés sont des
entiers naturels.

A chaque clé k, on associe une case en
prenant le reste de la division de k par m
H(k) = k mod m
Cette méthode est simple, mais peut donner
de mauvaises répartitions si m est mal choisi.

La fonction modulo

On choisit m premier assez éloigné des puissances de 2 et des
puissances de 10

Exemple : On veut une table de hachage pour conserver environs n =
2000 chaînes de caractères.

L’examen de 3 éléments en moyenne en cas de recherche infructueuse
n’est pas catastrophique

On alloue une table de taille m = 701



701 est premier
701 est proche de 2000/3
701 n’est pas proche d’une puissance de 2
(512 = 29 < 701 < 210 = 1024)
La fonction modulo

Pour des chaînes de caractères, on applique
le même principe en prenant pour k le
nombre formé en concaténant les caractères.


En additionnant les codes ascii des caractères
En représentant chaque caractère en base 256
Conclusion

Les tables de hachage ont de gros avantages
…

… mais aussi des inconvénients, si le
nombre de données est important la fonction
de hachage devient critique.