Académique Documents
Professionnel Documents
Culture Documents
Olivier Aumage
LIP, ENS Lyon (bureau 302),
46, allée d’Italie, 69364 Lyon Cedex 07
email : Olivier.Aumage@ens-lyon.fr
Octobre 2001
2
Table des matières
1 Introduction 5
1.1 Définition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2 Au programme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2 Listes chaînées 7
2.1 Listes simplement chaînées . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1.1 Principe, forme générale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Notion de maillon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Maillon suivant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Notion de liste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Définitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1.2 Définition en C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Le maillon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
La liste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Types à usage public, types à usage privé . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.1.3 Fonctions de parcours simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Longueur de la liste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Affichage de la liste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.1.4 Fonctions de modification de la liste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Insertion en tête . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Suppression en tête . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Insertion en queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Suppression en queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.1.5 Duplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
La notion d’aliasing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Duplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2 Autres formes de listes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2.1 Listes doublement chaînées . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Déclaration des maillons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Déclaration de la liste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.2.2 Listes circulaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Principe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3 Structures dérivées . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3.1 Piles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3.2 Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3 Arbres 13
3.1 Généralités . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.1.1 Principe, forme générale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Notion de nœud . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3
Notion d’arbre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Terminologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Arbres n-aires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.2 Arbres binaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.2.1 Déclaration en C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Le nœud . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
L’arbre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.2.2 Algorithmes simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Taille de l’arbre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Hauteur de l’arbre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.2.3 Parcours en profondeur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Exemple : affichage de l’arbre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Approche itérative . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.2.4 Parcours en largeur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.3 Autres formes d’arbres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.3.1 Arbres généralisés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Principe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Déclaration du nœud généralisé en C . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Déclaration de l’arbre en C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.4 Structures dérivées . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4 Tableaux et tables 21
4.1 Tableaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.1.1 Principe, forme générale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Définition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Terminologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.1.2 Définition en C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Tableaux de types simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Tableaux de structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.1.3 Opérateur crochets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.1.4 Fonctions de parcours simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Parcours linéaire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Parcours dichotomique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2 Chaînes de caractères . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2.1 Principe, forme générale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2.2 Définition en C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2.3 Fonctions de parcours simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.3 Tables de hachage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.3.1 Principe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Alvéoles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Résolution des collisions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Importance de la fonction de hachage . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.3.2 Définition en C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.3.3 Mise en œuvre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Fonction de hachage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Initialisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Ajout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Recherche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4
Chapitre 1
Introduction
1.1 Définition
Une structure dynamique est une structure dont la taille peut varier en fonction des besoins.
1.2 Au programme
Il est prévu de voir les structures suivantes :
1. listes chaînées ;
2. arbres ;
3. tableaux et tables.
5
6
Chapitre 2
Listes chaînées
Maillon suivant
Le champ pointeur vers un maillon pointe vers le maillon suivant de la liste. S’il n’y a pas de maillon
suivant, le pointeur vaut NULL.
Notion de liste
Une liste simplement chaînée est un pointeur sur un maillon. Une liste vide est une liste qui ne contient
pas de maillon. Elle a donc la valeur NULL.
Définitions
La terminologie suivante est généralement employée :
– le premier maillon de la liste est appelé tête ;
– le dernier maillon de la liste est appelé queue.
2.1.2 Définition en C
Le maillon
La déclaration des types constituant le maillon est la suivante :
1 typedef struct s_maillon *p_maillon_t;
3 {
4 int valeur;
5 p_maillon_t suivant;
6 } maillon_t;
7
La liste
2 {
4 int longueur = 0;
7 {
8 longueur++;
9 p_maillon = p_maillon->suivant;
10 }
11
12 return longueur;
13 }
– Version récursive :
1 int longueur_r(liste_t liste)
2 {
5 if (p_maillon != NULL)
6 {
7 return 1 +
8 longueur_r(p_maillon->suivant);
9 }
10
11 return 0;
12 }
8
Affichage de la liste
Note : les fonctions suivantes sont données uniquement en version récursive, mais les versions itératives
sont également possibles.
2 {
5 if (p_maillon)
6 {
8 affichage(p_maillon->suivant);
9 }
10 else
11 {
12 printf("\n");
13 }
14 }
2 insertion_en_tete(p_liste_t p_liste,
3 int entier)
4 {
8 p_maillon_nouveau = malloc(sizeof(maillon_t));
10 p_maillon_nouveau->valeur = entier;
11 p_maillon_nouveau->suivant = p_maillon_ancien;
12
13 *p_liste = p_maillon_nouveau;
14 }
Suppression en tête
1 int
2 suppression_en_tete(p_liste_t p_liste)
3 {
5 int resultat = 0;
9
7 if (p_maillon != NULL)
8 {
9 resultat = p_maillon->valeur;
10 *p_liste = p_maillon->suivant;
11 free(p_maillon);
12 }
13
14 return resultat;
15 }
Insertion en queue
1 void
2 insertion_en_queue(p_liste_t p_liste,
3 int entier)
4 {
7 if (p_maillon == NULL)
8 {
9 insertion_en_tete(p_liste, entier);
10 }
11 else
12 {
13 insertion_en_queue(&(p_maillon->suivant), entier);
14 }
15 }
Suppression en queue
1 int
2 suppression_en_queue(p_liste_t p_liste)
3 {
5 int resultat = 0;
7 if (p_maillon != NULL)
8 {
9 if (p_maillon->suivant == NULL)
10 {
11 resultat = suppression_en_tete(p_liste);
12 }
13 else
14 {
15 resultat =
10
16 suppression_en_queue(&(p_maillon->suivant));
17 }
18 }
19
20 return resultat;
21 }
2.1.5 Duplication
La notion d’aliasing
À la suite d’une erreur de programmation, il est possible que des maillons de listes différentes soient
mélangés. Concrêtement, deux maillons de deux listes différentes pointent vers le même maillon. Ce dernier
est donc accessible depuis deux listes différentes. Ce phénomène est appelé aliasing. Il doit absolument être
évité.
Duplication
1 liste_t dup(liste_t liste_source)
2 {
6 if (p_maillon_source != NULL)
7 {
8 p_maillon_destination = malloc(sizeof(maillon_t));
10 p_maillon_destination->valeur = p_maillon_source->valeur;
11 p_maillon_destination->suivant = dup(p_maillon->suivant);
12 }
13
14 return p_maillon_destination;
15 }
3 {
4 int valeur;
5 p_maillon_t precedent;
6 p_maillon_t suivant;
7 } maillon_t;
11
Déclaration de la liste
1 typedef struct s_liste
2 {
3 p_maillon_t tete;
4 p_maillon_t queue;
5 } liste_t;
2.3.2 Files
Les files sont aussi appelées queue (en anglais) ou FIFO (First-In, First-Out) : le premier élément ajouté
est le premier retiré.
Les files sont accessibles uniquement avec les deux fonctions suivantes :
– void enqueue(file, objet) ajoute un objet à la file ;
– objet dequeue(file) enlève et retourne le premier objet de la file.
12
Chapitre 3
Arbres
3.1 Généralités
3.1.1 Principe, forme générale
Notion de nœud
L’élément de base d’un arbre s’appelle le nœud. Il est constitué :
– d’un champ de donnée ;
– d’un ou plusieurs pointeurs vers des nœuds.
Notion d’arbre
Un arbre est un pointeur sur un nœud. Un arbre vide est un arbre qui ne contient pas de nœud. Il a donc
la valeur NULL.
Terminologie
On utilise classiquement la terminologie suivante pour décrire les arbres :
Père Le père A d’un nœud B est l’unique nœud tel que :
– un des sous-arbres contient B
– hauteur(A) − hauteur(B) = 1.
Fils Les fils d’un nœud sont les nœuds de ses sous-arbres de hauteur immédiatement inférieure.
Frères Les frères d’un nœud A sont les nœuds qui possèdent le même père que A.
Sous-arbre Un sous-arbre d’un nœud A est un arbre dont la racine est un fils de A.
Racine La racine de l’arbre est l’unique nœud qui n’a pas de père.
Feuille Une feuille de l’arbre est un nœud qui n’a pas de fils.
Branche Un arc qui relie deux nœuds est une branche.
Hauteur Définition récursive :
– La hauteur d’un arbre vide est nulle.
– La hauteur d’un arbre non-vide est égale à la hauteur de sa racine.
– La hauteur d’un nœud est égale à 1 plus le maximum des hauteurs de ses sous-arbres.
Arbres n-aires
Un arbre dont les nœuds ont au plus n fils est un arbre n-aire. Lorsque n vaut 2, l’arbre est dit binaire.
Dans le cas particulier de l’arbre binaire on utilise les termes de fils gauche et fils droits d’un nœud, ainsi que
les notions de sous-arbre gauche et de sous-arbre droit.
13
3.2 Arbres binaires
La forme d’arbre la plus simple à manipuler est l’arbre binaire. De plus les formes plus générales
d’arbres (avec n > 2) peuvent être représentées par des arbres binaires.
3.2.1 Déclaration en C
Le nœud
La déclaration des types constituant le nœud est la suivante :
1 typedef struct s_noeud *p_noeud_t;
3 {
4 int valeur;
5 p_noeud_t fils_gauche;
6 p_noeud_t fils_droit;
8 /* Optionnellement */
9 p_noeud_t pere;
10 } noeud_t;
Le pointeur vers le nœud père est optionnel. Il sert simplement à simplifier l’écriture et la complexité de
certains algorithmes. Le choix de l’utilisation ou non d’un pointeur père est à rapprocher du choix entre
une liste simplement chaînée et une liste doublement chaînée au chapitre précédent.
L’arbre
La déclaration des types constituant l’arbre est la suivante :
1 typedef p_noeud_t arbre_t;
2 {
5 if (p_noeud)
6 {
8 }
10 return 0;
11 }
14
Hauteur de l’arbre
La fonction hauteur calcule la hauteur de l’arbre de manière récursive. Elle utilise une fonction max
qui retourne le maximum de deux entiers. Si l’arbre est vide, la fonction hauteur retourne 0. Si l’arbre
contient au moins un nœud, la fonction hauteur retourne le maximum des hauteurs de ses sous-arbres
plus 1.
2 {
3 if (a > b)
4 {
5 return a;
6 }
8 return b;
9 }
10
12 {
14
15 if (p_noeud)
16 {
17 return 1 + max(hauteur(p_noeud->fils_gauche)
18 + hauteur(p_noeud->fils_droit));
19 }
20
21 return 0;
22 }
Les trois versions du parcours en profondeur récursif sont présentées ci-après. Pour chaque version, la
fonction disp affiche le contenu de l’arbre sous la forme d’une ligne de nombres entiers séparés par des
espaces.
Parcours préfixe Le traitement effectué sur les nœuds par la fonction disp est l’affichage du contenu
du nœud. Dans ce premier parcours préfixe, le traitement du nœud courant a lieu avant les deux appels
récursifs.
15
1 void disp(arbre_t arbre)
2 {
5 if (p_noeud)
6 {
8 disp(p_noeud->fils_gauche);
9 disp(p_noeud->fils_droit);
10 }
11 }
Parcours infixe
2 {
5 if (p_noeud)
6 {
7 disp(p_noeud->fils_gauche);
9 disp(p_noeud->fils_droit);
10 }
11 }
Parcours postfixe
2 {
5 if (p_noeud)
6 {
7 disp(p_noeud->fils_gauche);
8 disp(p_noeud->fils_droit);
10 }
11 }
Approche itérative
L’algorithme du parcours en profondeur préfixe peut être programmé très simplement selon une ap-
proche itérative en utilisant une structure de donnée supplémentaire : une pile (cf. section 2.3.1).
2 {
16
3 p_noeud_t p_noeud = arbre;
6 if (noeud)
7 {
8 push(pile, p_noeud);
10 do
11 {
12 p_noeud = pop(pile);
13
15
16 if (p_noeud->fils_droit)
17 {
18 push(pile, p_noeud->fils_droit);
19 }
20
21 if (p_noeud->fils_gauche)
22 {
23 push(pile, p_noeud->fils_gauche);
24 }
25 }
26 while (pile);
27 }
28 }
2 {
6 if (noeud)
7 {
8 enqueue(file, p_noeud);
10 do
11 {
12 p_noeud = dequeue(file);
13
17
14 printf("%d ", p_noeud->valeur);
15
16 if (p_noeud->fils_gauche)
17 {
18 dequeue(file, p_noeud->fils_gauche);
19 }
20
21 if (p_noeud->fils_droit)
22 {
23 dequeue(file, p_noeud->fils_droit);
24 }
25 }
26 while (file);
27 }
28 }
Pour repésenter des arbres quelconques on utilise une variante de la représentation fils gauche/fils droit
appelée fils gauche/frère droit. Chaque nœud contient un pointeur vers son premier fils (le plus à gauche)
et un pointeur vers son frère droit (et éventuellement un pointeur vers son père comme pour la représen-
tation d’un nœud d’arbre binaire). Avec ce schéma, le nombre de fils d’un nœud donné est arbitraire et
indépendant du nombre de fils des autres nœuds.
3 {
4 int valeur;
5 p_noeud_gen_t fils_gauche;
6 p_noeud_gen_t frere_droit;
8 /* Optionnellement */
9 p_noeud_gen_t pere;
10 } noeud_gen_t;
Déclaration de l’arbre en C
18
3.4 Structures dérivées
– Les forêts sont des structures constituées d’un ou plusieurs arbres. Une manière de représenter une
forêt est d’utiliser un nœud généralisé ayant pour fils chacun des arbres de la forêt.
– Les treillis sont des structures similaires aux arbres, à ceci près que les nœuds peuvent avoir plusieurs
parents.
– Les graphes, orientés ou non, sont des structures encore plus générales que les arbres : chaque nœud
(souvent appelé sommet) contient une valeur et un certain nombre de pointeurs vers d’autres som-
mets appelés arêtes. Il n’y a plus de notion de parenté.
19
20
Chapitre 4
Tableaux et tables
4.1 Tableaux
4.1.1 Principe, forme générale
Définition
Un tableau — aussi appelé un vecteur — est un ensemble d’éléments de même type représentés consé-
cutivement en mémoire et désignés par un pointeur vers le premier de ces éléments.
Terminologie
4.1.2 Définition en C
Tableaux de types simples
Tableaux statiques La définition d’un tableau statique (dont la taille ne peut pas être modifiée en cours
d’exécution) en C est la suivante :
1 {
2 int t[10];
3 ...
4 }
Tableaux dynamiques La définition d’un tableau dynamique d’éléments de type simples en C est la sui-
vante :
21
1 {
2 int *t = NULL;
3 int n = 10;
5 t = calloc(10, sizeof(int));
6 ...
7 free(t);
8 }
Tableaux de structures
Tableaux statiques
4 /* Type "ma_structure_t" */
6 {
7 int champ_int;
8 double champ_double;
9 } mad_structure_t;
10
11 {
12 p_ma_structure_t t[10];
13 int i = 0;
14
16 {
17 t[i] = malloc(sizeof(ma_structure_t));
18 t[i]->champ_int = 1;
19 t[i]->champ_double = 3.1415926;
20 ...
21
22 }
23 ...
24
26 {
27 free(t[i]);
28 t[i] = NULL;
29 }
30 }
Tableaux dynamiques
22
1 /* Type "pointeur sur ma_structure_t" */
4 /* Type "ma_structure_t" */
6 {
7 int champ_int;
8 double champ_double;
9 } mad_structure_t;
10
11 {
12 p_ma_structure_t *t = NULL;
13 int n = 10;
14 int i = 0;
15
16 t = calloc(n, sizeof(p_ma_structure));
17
19 {
20 t[i] = malloc(sizeof(ma_structure_t));
21 t[i]->champ_int = 1;
22 t[i]->champ_double = 3.1415926;
23 ...
24
25 }
26 ...
27
29 {
30 free(t[i]);
31 t[i] = NULL;
32 }
33
34 free(t);
35 }
23
4.1.4 Fonctions de parcours simples
Sauf mention contraire, les fonctions ci-dessous portent sur des tableaux d’entiers.
Parcours linéaire
Affichage itératif
2 {
3 int i = 0;
6 {
7 printf("%d\n", t[i]);
8 }
9 }
Affichage récursif
2 {
3 if (n)
4 {
5 printf("%d\n", *t);
6 disp(t + 1, n - 1);)
7 }
8 }
Recherche
2 {
4 int i = 0;
7 {
8 if (t[i] == entier)
9 {
10 return i;
11 }
12 }
13
14 return -1;
15 }
24
Parcours dichotomique
L’utilisation d’algorithmes dichotomiques suppose que le tableau à traiter soit trié.
Recherche dichotomique
1 int find_d(int *t, int n, int entier)
2 {
4 int a = 0;
5 int b = n;
7 while (a < b)
8 {
9 int i = (b + a) / 2;
10
11 if (entier == t[i])
12 {
13 return i;
14 }
16 {
17 b = i;
18 }
19 else
20 {
21 a = i + 1;
22 }
23 }
24
25 return -1;
26 }
4.2.2 Définition en C
Tableaux statiques de caractères
1 {
25
3
6 }
2 char *c = NULL;
10 free(C);
11 }
2 {
3 int l = 0;
6 {
7 l++;
8 }
10 return l;
11 }
Version 2 :
1 int my_strlen(char *s)
2 {
3 char *p = s;
6 {
7 p++;
8 }
10 return p - s;
11 }
26
Version 3 :
1 int my_strlen(char *s)
2 {
3 char *p = s;
5 while (*p)
6 {
7 p++;
8 }
10 return p - s;
11 }
2 {
4 {
5 s_src++;
6 s_dst++;
7 }
8 }
2 {
3 while (*s_dst)
4 {
5 s_dst++;
6 }
8 my_strcpy(s_dst, s_src);
9 }
2 {
4 {
5 if (!*s1)
6 {
7 return 0;
8 }
27
9
10 s1++;
11 s2++;
12 }
13
15 }
Alvéoles
Une table de hachage est constituée d’un ensemble de m alvéoles. L’idée de base est d’utiliser une
fonction h : U → {1, . . . , m − 1} de la clé pour déterminer l’objet à trouver (ou plutôt l’alvéole dans laquelle
se trouve l’objet à trouver) — et non la clé elle même, comme c’est le cas pour les tableaux.
4.3.2 Définition en C
Une définition possible (clés de type int, valeurs de type int) est la suivante :
1 /* Liste de chainage */
4 {
5 int cle;
6 int valeur;
7 p_maillon_t suivant;
8 } maillon_t;
10 /* Table */
28
11 typedef struct s_table *p_table_t;
13 {
14 int n;
15 p_maillon_t *alveoles;
16 } table_t;
Une définition plus complexe (clés de type char, valeurs de type char) :
3 {
4 char * cle;
5 void * valeur;
6 p_maillon_t suivant;
7 } maillon_t;
14 {
15 int m;
16 listes *alveoles;
17 } table_t;
Fonction de hachage
Une fonction de hachage rudimentaire est la suivante.
2 {
3 int x = 0;
5 while (*cle)
6 {
7 x += *cle;
8 cle++;
9 }
10
11 return cle % m;
12 }
29
Initialisation
1 p_table_t init(int m)
2 {
3 p_table_t t = NULL;
5 t = malloc(sizeof(table_t));
6 t->m = m;
9 return t;
10 }
Ajout
2 {
3 int a = 0;
4 p_maillon_t m = NULL;
6 a = h(t->m, cle);
7 m = t->alveoles[a];
9 while (m)
10 {
11 if (strcmp(m->cle, cle) == 0)
12 break;
13
14 m = m->suivant;
15 }
16
17 if (!m)
18 {
19 m = malloc(sizeof(maillon_t));
21 strcpy(m->cle, cle);
22 m->suivant = t->alveoles[a];
23 t->alveoles[a] = m;
24 }
25
26 m->valeur = objet;
27 }
30
Recherche
1 void *recherche(p_table_t t, char *cle)
2 {
3 int a = 0;
4 p_maillon_t m = NULL;
6 a = h(t->m, cle);
7 m = t->alveoles[a];
9 while (m)
10 {
11 if (strcmp(m->cle, cle) == 0)
12 return m->valeur;
13
14 m = m->suivant;
15 }
16
17 return NULL;
18 }
-=-=-=-
31