Null 5
Null 5
Null 5
VI-1-1 Introduction
On utilise souvent en informatique une structure appelée "Table" ou dictionnaire pour ranger des Informations
en mémoire. Une table est un ensemble de couples <clé, information> où chaque clé n’apparaît qu’une seule fois
dans la table.
Exemples :
24) Annuaire téléphonique
Clé (Prénom) Information (Tél + Adresse)
MBALLA 699999999 Avenue Foé
KAMDEM 677777777 Rond pont Deido
. . .
25) Dictionnaire
Clé (Mot) Information (Signification/définition)
Arbre Graphe connexe sans cycle
Table Ensemble de couples <clé, info>
. .
26) Codage
Clé (Mot) Information(Code)
a 001
b 010
. .
Le problème posé est : comment organiser la table pour que les accès (recherche, insertion, suppression) soient
les plus rapides possibles ?
b- Fonctions de Hachage
On trouve plusieurs types de fonctions utilisées en Hashcoding :
1. h(clé) = (CodeASCII ( 1er car) + Code ASCII(2eme`car) ) mod N Si la clé est une chaine de caractères (nom)
2. h(clé) = clé mod N Si clé est une valeur numérique.
3. Méthode du milieu du carré
– Clé = 453
– (Cl)2 = (453)2 = 205209
– h(453) = 52
Si n > 100, on prend 3 chiffres.
La fonction de hachage doit donner des valeurs entières dans l’intervalle des indices de la tables : 0 <=h(cle´) <= N.
En plus, cette fonction doit être la plus distribuée possible sur cet intervalle, pour que les informations
ne se concentrent pas dans une partie de la table.
Un exemple de cas :
Toute la difficulté consiste à écrire une fonction de hachage correcte. Comment transformer une chaîne de
caractères en un nombre unique ?
La fonction de hachage doit nous retourner un indice d’une case de la table, dans laquelle se trouve l’information.
Plus besoin de parcourir toutes les cases (comme c’est le cas avec les Liste Linéaires
Imaginons donc un tableau de 100 cases dans lequel on va stocker des pointeurs vers des structures Etudiants
Etudiant * tableau[100];
Nous devons écrire une fonction qui, à partir d'un nom, génère un nombre compris entre 0 et 99 (les indices du
tableau). C'est là qu'il faut être inventif. Il existe des méthodes mathématiques très complexes pour « hacher » des
données, c'est-à-dire les transformer en nombres. Les algorithmes MD5 et SHA1 sont des fonctions de hachage
célèbres, mais elles sont trop poussées.
On peut inventer notre propre fonction de hachage. Ici, pour faire simple, on peut simplement additionner les valeurs
ASCII de chaque lettre du nom de l’Etudiant, à laquelle somme on applique le modulo (reste de la division) de 100.
Ainsi, l’indice se trouvera forcement dans la table.
int hachage(char *chaine){
int i = 0, nombreHache = 0;
for (i = 0 ; chaine[i] != '\0' ; i++){
nombreHache += chaine[i];
}
nombreHache %= 100;
return nombreHache;
}
c- Problème de collisions
Un problème sérieux se pose avec les fonctions de hachage si deux clés différentes donnent lieu à une même
adresse lorsqu’on leur applique la fonction de hachage, c-à-d
h(cle´1) = h(cle´2).
Une telle situation est appelée « collision » et plusieurs solutions existent pour sa résolution.
c-1 Les listes linéaires chaînées
Elle consiste à placer toutes les clés qui donnent le même indice qu’une clé existante dans une liste linéaire
chainée, appelée liste de débordement :
On doit garder, dans ce cas, une case toujours vide pour indiquer la fin de la recherche, c-à-d une valeur interdite
dans les clés.
c-2 Chaînage interne séparé
On ajoute à la table une partie réservée aux collisions de taille M. La taille de la table sera donc N + M.
On insère l’élément en collision dans la première place vide dans la partie des collisions et on le relie par un chaînage.
Exemple :
VI-1-4 Exercices
1- Proposer une structure de données efficace qui permet d’organiser et de stocker la liste des étudiants de
l’UdM. (Repérer les aspects statiques et dynamiques afin de proposer une structure de table)
1.1- Ecrire un algorithme qui insère un nouvel étudiant de IRT2.
1.2- Ecrire un algorithme qui recherche un étudiant à partir de son matricule.
2- On veut enregistrer un annuaire téléphonique sur micro, en utilisant la méthode de Hash-Coding. Chaque
entrée de la table représente les informations concernant une personne (Nom, prénom, Numéro de téléphone). La clé
considérée est le nom, et la fonction de hachage est donnée par :
H(cle) = (CodeASCII(1er car) + CodeASCII(2eme`car)) Mod N(5.1)
Où N qui est la taille de la table est égale à 100.
Remarque : les caractères peuvent être en majuscule ou en minuscule et il ne doit pas y avoir de distinction.
Questions :
– Décrire les structures de données nécessaires à la représentation des données en cas d’utilisation de la méthode
des LLCs pour résoudre les collisions.
– Ecrire les procédures de recherche, d’insertion et de suppression.
– Répéter les mêmes questions en utilisant la méthode d’essai linéaire.
– Répéter les mêmes questions en utilisant la méthode de chaînage interne séparé.
L'arbre est constitué de nœuds reliés entre eux de façon hiérarchique par des arrêtes. Le premier nœud est appelé
racine les derniers, ceux après lesquels il n'y a plus de nœud sont les feuilles. Un parcours de la racine vers une
feuille est une branche. Chaque nœud peut être considéré comme la racine d'un sous-arbre constitué de sa
descendance et de lui-même. L'arbre est de ce fait une structure récursive. Dans l'exemple ci-dessus chaque sous-
arbre correspond à un parenthésage. Une information parenthésée peut traduire un arbre.
L'expression : ( personne( nom, prénom, adresse( numéro, rue, ville, département) ) ) est celle de l'arbre :
Chaque étage de l'arbre est appelé niveau et les niveaux sont numérotés de 1 la racine à n la feuille la plus basse. La
hauteur d'un arbre c'est le niveau maximum atteint par une feuille. La hauteur de l'arbre ci-dessus est 3. Souvent on
parle de nœuds parents et de noeud fils. Les noeuds fils sont ceux qui descendent d'un noeud parent et seule la racine
n'a pas de parent. Dans l'exemple ci-dessus, personne est la racine, il est parent de nom, prénom et adresse qui sont
ses fils. Adresse est parent de numéro, rue, ville, département et numéro, rue, ville,département sont fils de adresse.
Les fils d'un même parent sont frères
Un chapitre de cours
Un sommaire de livre scientifique, un chapitre de cours sont construits selon une arborescence, par exemple :
Exemple :
A est la racine.
B est parent de D et E
D et E sont enfants de B
D et E sont frères (ou siblings)
D, E, F, G, I sont les noeuds externes ou feuilles
A, B, C, H sont les noeuds internes
La hauteur (profondeur) de l'arbre est 4
E est à la profondeur 3
Le degré du noeud C est 3.
C'est un arbre à quatre niveaux. Le nombre maximum possible de noeuds avec quatre niveaux est 24-1 noeuds, c'est
à dire 16-1, 15 noeuds. Il faudrait pour ce faire que tous les noeuds du niveau trois possèdent deux fils, un à gauche,
un à droite. Un tel arbre binaire est dit un arbre binaire complet.
Remarques
1) Une clé n’apparait au plus qu’une seule fois dans un arbre de recherche.
2) Deux ABR peuvent contenir les mêmes valeurs de clés mais être différents.
– Parcours en profondeur
– Parcours en largeur
La fonction suivante retourne l’adresse du nœud contenant une valeur recherchée ou NULL si la valeur recherchée
ne se trouve pas dans l’arbre.
Cas
Action
FG(N) FD(N) Exemple
NULL NULL Feuille (2,4,17) Remplacer N par NULL
3.1 Définition
Un tas (heap en anglais) est un arbre qui vérifie les deux propriétés suivantes :
3) C’est un arbre binaire complet c’est-à-dire un arbre binaire dont tous les niveaux sont remplis sauf
éventuellement le dernier où les éléments sont rangés le plus à gauche possible.
4) La clé de tout nœud est supérieure à celle de ses descendants.
5) L’élément le plus prioritaire se trouve donc toujours à la racine.
Exemple d’un tas :
3.2.1 Ajout
Pour ajouter un nouvel élément dans le tas on doit :
1. Créer un nœud contenant la valeur de cet élément,
2. Attacher ce nœud dans le dernier niveau dans la première place vide le plus à gauche possible (créer
un nouveau niveau si nécessaire). On obtient toujours un arbre binaire complet mais pas nécessairement
un tas.
3. Comparer la clé du nouveau nœud avec celle de son père et les permuter si nécessaire, puis
recommencer le processus jusqu’il n’y ait plus d’éléments à permuter.
3.2.2 Retrait
L’élément le plus prioritaire se trouve toujours à la racine, donc le retrait consiste à lire la racine puis la supprimer.
Pour ce faire on doit :
1. Remplacer la valeur de la racine par la valeur de l’élément le plus à droite dans le dernier niveau.
2. Supprimer de l’arbre cet élément (le plus à droite dans le dernier niveau), on obtient un arbre binaire
mais pas nécessairement un tas.
3. On compare la valeur de la racine avec les valeurs de ses deux fils et on la permute avec la plus
grande. On recommence le processus jusqu’il n’y ait plus d’éléments à permuter.
Exemple :
On remarque sur le tableau obtenu que le fils gauche d’un élément d’indice i se trouve toujours s’il
existe à la position 2i, et son fils droit se trouve à la position (2i + 1) et son père se trouve à la position
i/2. Les opérations d’ajout et de retrait sur le tas statique se font de la même façon que dans le cas du tas
dynamique. Avec ce principe les opérations d’ajout et de retrait se font d’une manière très simple et
extrêmement efficace. Les tas sont utilisés même pour le tri des tableaux : on ajoute les éléments d’un
tableau à un tas, puis on les retire dans l’ordre décroissant.
4.4 Exercices
1. Arbres de recherche binaires
(a) Compréhension
– Construire un arbre de recherche binaire à partir des clés ordonnées suivantes :
25 60 35 10 5 20 65 45 70 40 50 55 30 15
– Ajouter à l’arbre obtenu et dans l’ordre, les éléments suivants :
22 62 64 4 8
– Supprimer de l’arbre obtenu et dans l’ordre les éléments suivants :
15 70 50 35 60 25
(b) Écrire sur les arbres de recherche binaires les fonctions récursives qui retournent :
– Vrai si un nœud donné est une feuille et Faux sinon.
– Le nombre de feuilles de l’arbre.
– La taille de l’arbre.
– Le père d’un nœud donné.
– Le successeur d’un nœud donné (l’élément immédiatement supérieur).
– Le prédécesseur d’un nœud donné (l’élément immédiatement inférieur).
A. KENGNE || Algorithmique et structures de données 56
-UdM/FST-
– Le maximum dans un arbre donné.
– Le minimum dans un arbre donné.
– La hauteur d’un arbre.
(c) Écrire les algorithmes d’insertion et de suppression dans un ABR.
(d) Écrire la fonction qui crée un arbre binaire de recherche équilibré à partir d’un tableau trié.
(e) Écrire un algorithme de parcours en profondeur dans un arbre de recherche binaire:
▪ Préordre (Père FG FD)
▪ Inordre (FG Père FD)
▪ PostOrdre (FG FD Père)
2. Tas
(a) Compréhension
– Construire un tas à partir des clés ordonnées suivantes :
25 60 35 10 5 20 65 45 70 40 50 55 30 15
– Ajouter au tas et dans l’ordre les éléments suivants :
22 62 64 4 8
– Supprimer du tas et dans l’ordre les éléments suivants :
15 70 50 35 60 25
(b) Écrire les algorithmes d’insertion et de suppression dans un tas statique.
(c) Écrire les algorithmes d’insertion et de suppression dans un tas dynamique.