Vous êtes sur la page 1sur 50

Université de la Manouba

Institut Supérieur des Arts et Multimédias

Algorithme et Structures

des Données 2
Support de cours

Mohamed Mohsen Gammoudi,


Professeur en informatique
Emai : gammoudimomo@gmail.com

Farah HARRATHI
Maître Assistant en Informatique
E-mail : harrathi.farah@gmail.com

Année universitaire 2020 – 2021


Préface

Objectifs du cours :

Ce cours permettra aux étudiants de première année Licence fondamentale


informatique d’analyser un problème donné et de définir l’algorithme traduisant la
solution du problème d’une manière rigoureuse et prête à être traduite en utilisant
un langage de programmation quelconque, comme ça était demandé dans le
programme du LMD.
De plus, l’étudiant sera capable de définir la structure de données adéquate au
problème à résoudre et par conséquent celle qui permettra d’optimiser l’algorithme.
Nous attirons l’attention que ce support de cours est inspiré de plusieurs
références bibliographiques (livres et ressources disponibles sur le web).

Pré-requis : Algorithme et structures de données 1


Volume horaire : 21h, TD : 42h
Bibliographie :
FABER. (2009). FABER F. INTRODUCTION A LA PROGRAMMATION EN ANSI-C,
http://www.ltam.lu/cours-c/, Date de consultation : 28 Juin 2009 .
HARDOUIN. (2009). HARDOUIN L.
http://www.istia.univ-angers.fr/~hardouin/cours_c.pdf, Date de
constation : 19 Mai 2009 .
La Page de l'algorithmique. ( 2008).
La Page de l'algorithmique. http://algor.chez.com/index.html, .
LAPORTE.(2009). LAPORTE S.
http://btsig972.free.fr/cours/Algorithme/1e_annee/07.pdf, Date de
consultation : 09 Mai 2009 .
REBAINE.(1, 2009). REBAINE D.
http://wwwens.uqac.ca/~rebaine/8INF805/courslistespilesetfiles.pdf,
Date de consultation : 20 Mai 2009 .
REBAINE.(2, 2009). REBAINE D.
http://wwwens.uqac.ca/~rebaine/8SIF109/Les%20arbres.pdf, Date de
consultation : 10 Septembre 2009 .
Shaffer. (2001). Shaffer C A. Practical Introduction to Data Structures and Algorithm
Analysis (C++ Edition) (2nd Edition) (chapitre2) .
TThomas et al. (2002). Thomas H. Cormen, Charles E. Leireson, Ronald L Rivest et
Clifford Stein, . «Introduction à l’algorithmique», cours et exercices 2ème
cycle Ecoles d’ingénieurs » , Edition Dunod, 2ème dition, Paris 2002.

-i-
-ii-
Table des matières

1. Préface ................................................................................................................................... i
2. Table des matières............................................................................................................ 3
3. Table des figures ............................................................................................................... 5
4. Chapitre 1 : Les listes chaînées ..................................................................................... 6
1.1 Introduction ............................................................................................................................. 6
1.2 Notion de maillon ................................................................................................................... 6
1.3 Notion de liste chaînée ......................................................................................................... 6
1.4 Implémentation du type liste chaînée............................................................................ 7
1.4.1 Déclaration d’une variable de type liste........................................................................... 7
1.4.2 Accès aux champs d’un maillon d’une liste ..................................................................... 7
1.4.3 Initialisation d’une liste à Nil ................................................................................................ 8
1.5 Insertion d’une valeur en tête d’une liste ..................................................................... 8
1.6 Récupérer l’adresse du dernier élément d’une liste ................................................. 9
1.7 Insertion d’une valeur en queue d’une liste ............................................................. 10
1.8 Longueur d’une liste .......................................................................................................... 11
1.9 Insertion d’une valeur à une position k dans une liste ......................................... 11
1.10 Suppression du premier maillon d’une liste ........................................................... 13
1.11 Suppression du dernier maillon d’une liste ............................................................ 15
1.12 Suppression de tous les maillons d’une liste .......................................................... 16
1.13 Les listes circulaires.......................................................................................................... 16
5. Chapitre 2 : Les listes doublement chaînées ........................................................ 18
1.14 Les listes doublement chaînées.................................................................................... 18
1.14.1 Le type liste doublement chaînée ................................................................................... 18
1.14.2 Insertion d'un maillon (une valeur) en tête d’une liste doublement
chainée ........................................................................................................................................ 19
1.15 Insertion d’une valeur en queue d’une liste doublement chainée .................. 20
1.16 Insertion d’une valeur v à une position k dans une liste doublement
chainée ............................................................................................................................................. 22
1.17 Suppression du premier maillon d’une liste doublement chainée ................. 24
2.11 Suppression du dernier maillon d’une liste doublement chainée .................. 25
6. Chapitre 3 : Les piles ..................................................................................................... 27
3.11 Définition et exemple ....................................................................................................... 27

-iii-
3.12 Opérations sur les piles .................................................................................................. 27
3.13 Implantation d’une pile par liste chaînée ................................................................. 28
3.14 Les opérations sur unepile ............................................................................................. 28
7. Chapitre 4 : Les files ...................................................................................................... 30
4.1 Définition ................................................................................................................................ 30
4.2 Les opérations sur une file .............................................................................................. 30
4.3 Implantation d’une file par liste chaînée ................................................................... 31
4.4 Les opérations sur une file .............................................................................................. 32
8. Chapitre 5 : Les arbres.................................................................................................. 33
5.1 Introduction .......................................................................................................................... 33
5.2 Terminologie de base et définitions ............................................................................ 34
5.3 Parcours d’arbres ................................................................................................................ 34
9. Chapitre 6 : Les arbres binaires ................................................................................ 36
6.1 Définition ................................................................................................................................ 36
6.2 Implémentation du type arbre binaire ....................................................................... 37
6.2.1 Déclaration d’une variable de type arbre ..................................................................... 37
6.2.2 Accès aux champs d’un nœud d’un arbre binaire ..................................................... 38
6.3 Insertion d’un nœud d’une valeur v dans un arbre binaire ................................ 38
6.4 Parcours d’un arbre binaire ............................................................................................ 38
6.4.1 Parcours Prefixe ...................................................................................................................... 38
6.4.2 Parcours Infixe......................................................................................................................... 39
6.4.3 Parcours Postfixé .................................................................................................................... 39
6.5 Tester si un Nœud est une feuille ................................................................................. 39
6.6 Nombre de feuilles dans un arbre binaire ................................................................. 39
10. Chapitre 7 : Les arbres binaires de recherche ..................................................... 40
7.1 Définition ................................................................................................................................ 40
7.2 Ajout d’une valeur dans un ABR .................................................................................... 40
7.3 Recherche d’une valeur dans un ABR ......................................................................... 42
7.4 Recherche du nœud père d’une valeur dans un ABR ............................................ 43
7.5 Recherche du max d’un ABR ........................................................................................... 44
7.6 Suppression d’une valeur dans un ABR ...................................................................... 44
11. Webographie ................................................................................................................... 49

-iv-
Table des figures

Figure 1.1-Structure d’un maillon dans une liste chaînée ................................................ 6


Figure 1.2-Une liste chaînée ............................................................................................. 7
Figure 1.3-La liste avant l’insertion de la valeur val en tête ............................................ 8
Figure 1.4-La liste aprés l’insertion de la valeur val en tête ............................................ 8
Figure 1.5-La liste avant l’insertion .................................................................................. 9
Figure 1.6-La liste avant l’insertion de la valeur val en queue ...................................... 10
Figure 1.7-La liste aprés l’insertion de la valeur val en queue ...................................... 10
Figure 1.8-La liste avant l’insertion de la valeur val à la position k=2 ........................... 12
Figure 1.9-La liste aprés l’insertion de la valeur val à la position k=2 ........................... 12
Figure 1.10-La liste avant la suppression du premier élément ..................................... 14
Figure 1.11-La liste aprés la suppression du premier élément...................................... 14
Figure 1.12-La liste avant la suppresion du dernier maillon.......................................... 15
Figure 1.13-La liste aprés la suppresion du dernier maillon .......................................... 15
Figure 1.14-Une liste circulaire ....................................................................................... 17
Figure 2.1-Structure d’un maillon dans une liste doublement chaînée ......................... 18
Figure 1.7-La liste aprés l’insertion de la valeur val en queue d’une liste doublement
chainée ............................................................................................................................ 21
Figure 3.1 : La file résultat .............................................................................................. 31
Figure 3.2 : La file résultat àprés l’appel de Defiler (f) ................................................... 31
Figure 3.3 : La file résultat àprés l’appel de Enfiler (f, D) er Enfiler(f,E) ......................... 31
Figure 4.1: L'arbre de l’expression .................................................................................. 33
Figure 4.2 : Arbre représentant un livre ......................................................................... 34
Figure 5.1 : Exemple d’ arbre binaire .............................................................................. 36
Figure 6.1: Un arbre binaire de recherche ..................................................................... 40
Figure 6.2 : L’ ABR avant l’ajout de la valeur 6 ............................................................... 41
Figure 6.3 : L’ ABR aprés l’ajout de la valeur 6 ............................................................... 41

-v-
Chapitre 1 : Les listes chaînées

1.1 Introduction

Une liste chaînée permet de stocker un ensemble de valeur du même type, comme
un tableau. Contrairement au tableau, la taille de la liste chaînée peut varier au cours
du temps pas comme pour les tableaux où la taille est fixe. En effet, la liste n'est pas
allouée en une seule fois, mais les maillons sont alloués d'une manière
incrémentale.

1.2 Notion de maillon

L'élément de base d'une liste chaînée s'appelle le maillon. Il est constitué : d’un
champ de données et d'un champ pointeur vers un maillon.

Données
Pointeur

Figure 0.1-Structure d’un maillon dans une liste chaînée

Le champ pointeur vers un maillon contient l'adresse su maillon suivant de la


liste. On dit, il pointe sur le maillon suivant. S'il n'y a pas de maillon suivant, le
pointeur vaut NIL, car il ne contient aucune adresse.

1.3 Notion de liste chaînée

Dans une liste chaînée, chaque élément pointe, à l'aide d’un pointeur (suivant)
vers l'élément suivant dans la liste ; le dernier élément, par définition, n'a pas de
suivant, donc son pointeur suivant vaut nil.

-6-
p

Figure 0.2-Une liste chaînée

Pour manipuler une liste chaînée, nous manipulons un pointeur sur le premier
élément ; comme chaque élément « connaît » l'élément suivant, on peut ainsi accéder
à tous les éléments de la liste. Notons enfin que si le pointeur p vaut nil, cela signifie
que la liste est vide (elle ne contient aucun élément).
Le premier maillon de la liste est appelé tête, le dernier maillon de la liste est
appelé queue.

1.4 Implémentation du type liste chaînée

Un maillon est composé de deux champs de types hétérogènes, il est implémenté


en utilisant les enregistrements de la manière suivante :
Type maillon = Enregistrment
valeur : entier
suivant : ^maillon
FinEnregistrment

Par la suite, nous définissons le type liste comme étant un maillon.


Type liste = maillon

1.4.1 Déclaration d’une variable de type liste

Une fois le type liste est défini, on peut déclarer une variable de type pointeur sur
liste de la manière suivante :
p : ^liste

1.4.2 Accès aux champs d’un maillon d’une liste

Si p est un pointeur sur une variable de type liste, p^ est la variable (ou l'objet)
pointée par p. cette variable est un enregistrement, pour accéder à ses champs on
utilise l’opérateur "." .
p^. valeur
p^. suivant

-7-
1.4.3 Initialisation d’une liste à Nil

Une liste est vide si le pointeur du premier maillon vaut nil.


pNil

1.5 Insertion d’une valeur en tête d’une liste

Ecrire la procédure InserTete qui permet d’insérer une valeur val en tête d’une
liste chaînée donnée par l’adresse de son premier élément (p).
Notons qu’après l’insertion la valeur du premier sera changée, donc le passage
doit se faire par adresse.

Figure 0.3-La liste avant l’insertion de la valeur val en tête

p
val

Figure 0.4-La liste aprés l’insertion de la valeur val en tête

Principe

1. Créer un maillon d’adresse p1 contenant la valeur v


 p1 nouveau(^liste)
 p1^.valeurval
2. Créer un lien entre le nouveau maillon et la tête de la liste de telle sorte que p
soit le suivant de p1
 p1^.suivant p
3. Le maillon p1 devient le premier maillon de liste p
 p p1

-8-
Algorithme

PROCEDURE InsertTete(var p : ^liste, val : entier)


Variable
p1: ^liste
Debut
p1nouveau(^liste)
p1^.valeurval
p1^.suivant p
p p1
Fin

1.6 Récupérer l’adresse du dernier élément d’une liste

Ecrire la procédure Dernier qui renvoie l’adresse du dernier élément d’une liste
donnée par l’adresse de son premier élément (p).

Der

Figure 0.5-La liste avant l’insertion

Principe

Le dernier élément de la liste s’il existe est un maillon qui ne possède pas de
suivant. On fait le parcours de la liste, du premier élément jusqu’à trouver un maillon
dont le suivant vaut nil. L’adresse de ce maillon est renvoyée par la fonction Dernier
définie comme suit :

Algorithme

Fonction Dernier (p : ^liste) : ^liste


Debut
tantque(p <>Nil et p^.suivant<>Nil) faire
p  ^.suivant
Fintantque
Dernie p
Fin

-9-
1.7 Insertion d’une valeur en queue d’une liste

Ecrire la procédure InsertQueue qui permet d’insérer une valeur val dans une
liste chaînée donnée par l’adresse de son premier élément (p).
Notons qu’après l’insertion d’un maillon en queue, la valeur du premier peut
changer (dans le cas où la liste est vide), donc le passage doit se faire par adresse.

Figure 0.6-La liste avant l’insertion de la valeur val en queue

p
val

Der

Figure 0.5-La liste aprés l’insertion de la valeur val en queue

Principe

Deux cas :
1. Si la liste est vide l’insertion en queue est une insertion en tête.
Si (p =Nil) alors
InsertTete (p, val)
2. Sinon
 créer un maillon d’adresse p1 contenant la valeur v et dont l’élément
suivant est Nil
sinon
p1nouveau(^liste)
p1^.valeurval
p1^.suivantNil
 Récupérer l’adresse du dernier maillon et l’affecter à un pointer Der,
ensuite p1 devient le suivant de Der
Der  dernier(p)
Der^.suivantp1
Finsi

-10-
Algorithme

PROCEDURE InsertQueue (var p : ^Liste, val : entier)


Variable
p1, Der : ^liste
Debut
Si (p=Nil) alors
InsertTete(p,val)
Sinon
p1 nouveau(^liste)
p1^.valeurval
p1^.suivantNil// il sera le dernier
Der  dernier(p)
Der^.suivantp1
Finsi
Fin

1.8 Longueur d’une liste

Ecrire la fonction LongListe qui permet de renvoyer le nombre d’élément d’une


liste chaînée donnée par l’adresse de son premier élément (p). La fonction renvoie
0 si la liste est vide.

Principe

On fait le parcours de la liste, du premier élément jusqu’au dernier en


incrémentant un compteur de 1 à chaque passage d’un maillon à son suivant. La
valeur de ce compteur au départ vaut 0.
FONCTION LongListe (p : ^liste) : entier
Variable
L : entier
Debut
L0
Tantque (p <>Nil) faire
LL+1
p  p^.suivant
fintantque
LongListeL
Fin

1.9 Insertion d’une valeur à une position k dans une liste

Ecrire la procédure Insertk qui permet d’insérer une valeur val à une position k
dans une liste chaînée donnée par l’adresse de son premier élément (p). La valeur
val aura le rang k dans la liste après l’insertion.

-11-
Notons qu’après l’insertion la valeur de p peut changer (dans le cas où k=0) donc
le passage doit se faire par adresse.

Figure 0.7-La liste avant l’insertion de la valeur val à la position k=2

p
val

Pk-1
=2 pk

Figure 0.8-La liste aprés l’insertion de la valeur val à la position k=2

Principe

1. Si k=1 l’insertion se fait en tête de la liste.


Si (k =1) alors
InsertTete(p, val)
2. Sinon
si k = long(p)+1, l’insertion est Insertqueue(p, val)

sinon
si(k>LongListe(p))+1 alors
ecrire("la position k=" ,k, " n'existe pas car la liste est de
taille",LongListe(p))

 Sinon
- Récupérer l’adresse du maillon qui se trouve à la position k-1 (p2)
.
sinon
pour i de 1 a k-1 faire
p2p2^.suivant;
finpour

-12-
- créer un maillon d’adresse p1 contenant la valeur val et dont
l’élément suivant est Nil
p1nouveau (^liste)
p1^.valeurval
- Le suivant de p1 est le suivant de p2.
P1^.suivant p2^.suivant
- Le suivant de p2 est p1.
p2^.suivant p1
Finsi
Finsi

Algorithme

PROCEDURE Insertk(p:^liste , k: entier, val: entier)


Variable
p1, p2 : ^liste
i : entier
debut
si(k =1) alors
InsertTete (p,val)
sinon
si(k>LongListe(p)+1) alors
ecrire("la position k=" ,k, " n'existe pas car la liste est de
taille",LongListe (premier))
sinon
p2p
pour i de 1 a k-1 faire
p2p2^.suivant;
finpour
p1nouveau (^liste)
p1^.valeurval
p1^.suivantp2^.suivant
p2^.suivantp1
Finsi
Finsi
Fin

1.10 Suppression du premier maillon d’une liste

Ecrire la procédure SuppTete qui permet de supprimer le premier maillon d’une


liste chaînée donnée par l’adresse de son premier élément (p).
Notons qu’après la suppression, la valeur du pointeur p doit changer, donc le
passage doit se faire par adresse.

-13-
p

Figure 0.9-La liste avant la suppression du premier élément

Figure 0.10-La liste aprés la suppression du premier élément

Principe

2. si la liste est non vide


 on sauvegarde p dans une variable p2 .
si(p ≠ Nil) alors
p2p
 la valeur de p prend la valeur de son suivant.
pp^.suivant
 on libère la zone mémoire d’adresse p2.
liberer(p2)
finsi

Algorithme

PROCEDURE SuppTete( var p : ^Liste)


Variable
p2 : ^Liste
Debut
Si (p ≠ Nil) alors
p2 p
p  p ^.suivant
liberer(p2)
finsi
Fin

-14-
1.11 Suppression du dernier maillon d’une liste

Ecrire la procédure SuppQueue qui permet de supprimer le dernier maillon d’une


liste chaînée donnée par l’adresse de son premier élément (premier).
Notons qu’après la suppression la valeur du premier peut changer (dans le cas où
la liste contient un seul élément, longListe(premier)=1), donc le passage doit se faire
par adresse.

AvDer P2

Figure 0.61-La liste avant la suppresion du dernier maillon

Figure 0.72-La liste aprés la suppresion du dernier maillon

Principe

1. si la liste est vide ou la liste contient un seul élément, la suppression se fait en


tête de la liste
si (p = Nil ou LongListe(p)=1) alors
SuppTete(p)
2. Sinon,
 On récupère l’adresse de l’avant dernier élément (AvDer)
Sinon
AvDer  p
Tantque (AvDer ^.suivant^.suivant) faire
AvDer  AvDer ^.suivant
fintantque
 on sauvegarde l’adresse du dernier élément dans une variable p2.
p2  AvDer ^.suivant
 l’élément d’adresse AvDer devient le dernier élément.

-15-
AvDer ^.suivantNil
 on libère la zone mémoire d’adresse p2.
Liberer (p2)
finsi

Algorithme

PROCEDURE SuppFin(var p: ^liste)


Vaiable
AvDer, p2 : ^liste
Debut
Si ((p=Nil) ou LongListe(premier)=1)
SuppTete(p)
sinon
AvDer p
Tantque(AvDer ^.suivant^.suivant)faire
AvDer  AvDer ^.suivant
fintantque
p2  AvDer ^.suivant
AvDer ^.suivant  Nil
liberer(p2) / / zone mémoire ayant l’adresse p2 est libre
finsi
fin

1.12 Suppression de tous les maillons d’une liste

Ecrire la procédure SuppListe qui permet de supprimer tous les éléments d’une
liste chaînée donnée par l’adresse de son premier élément (p).
Notons qu’après la suppression, la valeur du premier vaut nil, donc le passage
doit se faire par adresse.

Algorithme

PROCEDURE Suppliste (var p : ^liste)


Debut
Tantque (p≠Nil) faire
SuppTete (p)
fintantque
fin

1.13 Les listes circulaires

Une liste où le pointeur nil du dernier élément est remplacé par l’adresse du
premier élément est appelée liste circulaire.

-16-
Théoriquement, dans une liste circulaire tous les maillons sont accessibles à
partir de n’importe quel autre maillon. Une liste circulaire n’a pas de premier et de
dernier maillon.
Par convention, on peut prendre le pointeur externe de la liste vers le dernier
élément et le suivant serait le premier élément de la liste.

Figure 0.83-Une liste circulaire

-17-
Chapitre 2 : Les listes doublement chaînées

1.14 Les listes doublement chaînées

Dans une liste doublement chaînée un maillon est composé de trois champs :
 un champ de données ;
 un pointeur vers le maillon suivant.
 un pointeur vers le maillon précédent.

Données
Précédent Suivant

Figure 2.9-Structure d’un maillon dans une liste doublement chaînée

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 NIL.
Précédent : Le champ pointeur vers un maillon pointe vers le maillon précédent
de la liste. S'il n'y a pas de maillon précédent, le pointeur vaut NIL.

1.14.1 Le type liste doublement chaînée

Type maillon = Enregistrment


Valeur : entier
Suivant : ^maillon
Precedent : ^maillon
FinEnregistrment

//Défintion du type listedc


type listedc =maillon

-18-
p

Figure 02.2-Une liste doublement chaînée

1.14.2 Insertion d'un maillon (une valeur) en tête d’une liste


doublement chainée.

Ecrire la procédure InserTete2 qui permet d’insérer une valeur v en tête d’une
liste doublement chaînée donnée par l’adresse de son premier élément (p).
Notons qu’après l’insertion la valeur du pointeur p sera changée donc le passage
doit se faire par adresse.

p
nil

Figure 02.3-insertion d’un maillon dans une liste doublement chaînée

p
nil

Figure 02.4-Une liste doublement chaînée

Principe

1) Créer un maillon d’adresse p1 contenant la valeur v et dont le pointeur


précédent est nil (il sera le premier).
p1 nouveau (^listedc)
p1^.valeurv
p1^.precedentNil
2) Créer un lien entre le nouveau maillon et la tête de la liste de telle sorte que p
soit le suivant de p1
p1^.suivantp
-19-
3) Créer un lien entre la tête de la liste (si elle existe) et le nouveau maillon de
telle sorte que p1 soit le précédent de p.
Si (p<>nil) alors
p^.precedentp1
Finsi
4) Le maillon p1 devient le premier maillon de liste p
pp1

Algorithme

PROCEDURE InsertTete2 (var p : ^listedc, v : entier)


Variable
p1 : ^listedc
Debut
p1  nouveau(^liste)
p1^.valeur v
p1^.precedent Nil
p1^.suivant p
si(p<>nil) alors
p^.precedentt p1
Finsi
p p1
Fin

1.15 Insertion d’une valeur en queue d’une liste doublement


chainée

Ecrire la procédure InsertQueue2 qui permet d’insérer une valeur val dans une
liste doublement chaînée donnée par l’adresse de son premier élément (p).
Notons qu’après l’insertion d’un maillon en queue, la valeur du premier peut
changer (dans le cas où la liste est vide), donc le passage doit se faire par adresse.

-20-
p

Figure 2.5-La liste avant l’insertion de la valeur val en queue d’une liste doublement chainée

Figure 0.6-La liste aprés l’insertion de la valeur val en queue d’une liste doublement chainée

Principe

Deux cas :
3. Si la liste est vide l’insertion en queue est une insertion en tête.
Si (p =Nil) alors
InsertTete2 (p, val)
4. Sinon
 créer un maillon d’adresse p1 contenant la valeur v et dont l’élément
suivant est Nil
sinon
p1nouveau(^liste)
p1^.valeurval
p1^.suivantNil
 Récupérer l’adresse du dernier maillon et l’affecter à un pointer Der,
ensuite p1 devient le suivant de Der
Der  dernier(p)
Der^.suivantp1
P1^.precedent der
Finsi

Algorithme

PROCEDURE InsertQueue2 (var p : ^Listedc, val : entier)


Variable
p1, Der : ^liste
Debut
Si (p=Nil) alors
InsertTete2(p,val)
Sinon

-21-
p1 nouveau(^liste)
p1^.valeurval
p1^.suivantNil// il sera le dernier
Der  dernier(p)
Der^.suivantp1
P1^.precedent der
Finsi
Fin

1.16 Insertion d’une valeur v à une position k dans une liste


doublement chainée

Ecrire la procédure Insertk qui permet d’insérer une valeur val à une position k
dans une liste chaînée doublement chainée donnée par l’adresse de son premier
élément (p). La valeur val aura le rang k dans la liste après l’insertion.
Notons qu’après l’insertion la valeur de p peut changer (dans le cas où k=0) donc
le passage doit se faire par adresse.

p
nil

Figure 02.7-Une liste doublement chaînée p

p
nil

Figure 02.7-insertion une valeur à la 2ème position dans une liste doublement chaînée

Principe

3. Si k=1 l’insertion se fait en tête de la liste.


Si (k =1) alors
InsertTete2(p, val)
4. Sinon
si k = long(p)+1, l’insertion est Insertqueue(p, val)

sinon
si(k>LongListe(p))+1 alors
ecrire("la position k=" ,k, " n'existe pas car la liste est de
taille",LongListe(p))

 Sinon

-22-
- Récupérer l’adresse du maillon qui se trouve à la position k-1 (p2)
.
sinon
pour i de 1 a k-1 faire
p2p2^.suivant;
finpour

- créer un maillon d’adresse p1 contenant la valeur val et dont


l’élément suivant est Nil
p1nouveau (^liste)
p1^.valeurval
- Le suivant de p1 est le suivant de p2.
P1^.suivant p2^.suivant
- Le suivant de p2 est p1.
P2^.suivant  p1
- Le precedent du suivant de p1 est p1.
P1^.precedent^.suivant p1
- Le precedent de p1 est p2.
P1^.precedent  p2
Finsi
Finsi

Algorithme

PROCEDURE Insertk2(p:^listedc , k: entier, val: entier)


Variable
p1, p2 : ^liste
i : entier
debut
si(k =1) alors
InsertTete2 (p,val)
sinon
si(k>LongListe(p)+1) alors
ecrire("la position k=" ,k, " n'existe pas car la liste est de taille",
LongListe (premier))
sinon
p2p
pour i de 1 a k-1 faire
p2p2^.suivant;
finpour
p1nouveau (^liste)
p1^.valeurval
P1^.suivant p2^.suivant
P2^.suivant  p1
P1^.precedent^.suivant p1
-23-
P1^.precedent  p2

Finsi
Finsi
Fin

1.17 Suppression du premier maillon d’une liste doublement


chainée

Ecrire la procédure SuppTete qui permet de supprimer le premier maillon d’une


liste chaînée donnée par l’adresse de son premier élément (p).
Notons qu’après la suppression, la valeur du pointeur p doit changer, donc le
passage doit se faire par adresse.

nil
P2
p

Figure 02.8- la liste avant la suppression du premier élément

p nil

Figure 2.9-la liste doublement chainée aprés la suppression du premier élément

Principe

2 si la liste est non vide


 on sauvegarde p dans une variable p2 .
si(p ≠ Nil) alors
p2p
 la valeur de p prend la valeur de son suivant.
pp^.suivant
 le précédent de p devient nil.
 p^.precedent  nil
 on libère la zone mémoire d’adresse p2.
liberer(p2)
finsi
-24-
Algorithme

PROCEDURE SuppTete2( var p : ^Listedc)


Variable
p2 : ^Liste
Debut
Si (p ≠ Nil) alors
p2  p
p p^.suivant
p^.precedent  nil
liberer(p2)
finsi
Fin

2.11 Suppression du dernier maillon d’une liste doublement


chainée

Ecrire la procédure SuppQueue2 qui permet de supprimer le dernier maillon


d’une liste chaînée doublement chainée donnée par l’adresse de son premier
élément (premier).
Notons qu’après la suppression, la valeur du premier peut changer (dans le cas
où la liste contient un seul élément, longListe(premier)=1), donc le passage doit se
faire par adresse.

Principe

3 si la liste est non vide


 on cherche le dernier maillon de p.
derdernier(p)
 le suivant de l’avant dernier devient nil.
der^.precedent^.suivant  nil
 On libère la mémoire occupée par le maillon d’adresse der.
liberer(der)
finsi

Algorithme

PROCEDURE SuppTete2( var p : ^Listedc)


Variable
der : ^Listedc
Debut
Si (p ≠ Nil) alors
der  dernier (p2)
der^.precedent^.suivant  nil
-25-
liberer(der)
finsi
Fin

p
nil

Der

Figure 2.10-Une liste doublement chaînée p avant suppression du dernier maillon queue

p
nil nil

Figure 2.11-Une liste doublement chaînée p après suppression

-26-
Chapitre 3 : Les piles

3.11 Définition et exemple

Une pile est une liste ordonnée sans fin d’éléments dans laquelle on ne peut
introduire ou enlever un élément qu'à une extrémité appelée tête de pile ou
sommet de pile.

Exemples : voir (figure 2.1)

 une pile d’assiettes,


 Une pile de conteneurs (containers en anglais) dans un navire de
commerce
 Pile de pages d’un site ou la navigation est faite par deux boutons
suivant et précédent
 Les caractères saisis en utilisant word. Quand vous annuler une saisie
vous ne pouvez annuler qu’à partir du dernier caractère saisi avec la
touche (CTR Z)

Figure 3.1 : Exemples de pile d’assiette [1] et de conteneurs [2].

Dans une pile, le dernier élément inséré sera le premier à être supprimé,
(retiré) : on parle de liste LIFO (Last In First Out).

3.12 Opérations sur les piles

Les opérations de base sur les piles sont :


 Empiler (p, e) (en anglais push) : empile l’élément e dans la pile p
 Dépiler (p) (en anglais pop): dépile un élément de la pile et retourne la
valeur de cet élément (e  Depiler (p))
Toutes les opérations sont effectuées sur la même extrémité; on parle de
structure en LIFO (Last In First Out).

-27-
Théoriquement, Il n’y a aucune limite au nombre d’éléments qu’on peut empiler.
Par contre, on ne peut dépiler d’une pile vide. A cet effet, on a une fonction
PileVide(p) qui retourne Vrai si la pile est vide sinon Faux.
InitialiserPile(p) ou ViderPile(p)
On peut vouloir aussi connaître le sommet de pile (la valeur de l’objet au
sommet) sans le supprimer (dépiler).
e  SommetDePile(p)

3.13 Implantation d’une pile par liste chaînée

L’implantation d’une pile par une liste (simplement) chaînée est une version
simplifiée de celle d’une liste par liste chaînée.
Type Pile=enregistrement (* un enregistrement dont le champ contient une liste chaînée *)
ListeElem : ^liste
finenregistrement

3.14 Les opérations sur une pile

PROCEDURE InitialiserPile(p : Pile)


Debut
p. ListeElem Nil le champ listeElement (* pointeur *)
fin

FONCTION PileVide(p : Pile) : booléen


Debut
PileVide( p. ListeElem =Nil)
Fin

PROCEDURE Empiler (p : Pile, e : entier)


Debut
InsertTete(p. ListeElem, e)
Fin

Procedure Dépiler (var p : Pile, var e : entier)


Variable
e : entier
Debut
si (PileVide(p)) alors
ecrire ("la pile est vide")
sinon
e p. ListeElem^.valeur
SuppTete(p. ListeElem)
finsi
Fin
-28-
FONCTION SommetDePile (p : Pile) : entier
Debut
si (PileVide(p)) alors
ecrire ("la pile est vide")
sinon
SommetDePile  p. ListeElem^.valeur
finsi
Fin

-29-
Chapitre 4 : Les files

4.1 Définition

Une file est une structure de données dynamique dans laquelle on insère des
nouveaux éléments à la fin (queue) et on enlève des éléments au début (tête de file)
(REBAINE, 1, 2009).

Exemples

 Clients devant un guichet,


 Les travaux en attente d’exécution dans un système de traitement par lots
 Les messages en attente dans un commutateur de réseau téléphonique.
 L’exécution des processus au niveau du système d’exploitation.
 Etc.

Figure 3.1 : Une file respectant le principe FIFO [3] Figure 3.2 : Une file qui ne
respecte pas le principe
FIFO [4]

Par principe, dans une file, le premier élément inséré est aussi le premier retiré.
On parle de mode d’accès FIFO (Fisrt In Fist Out). Contrairement à la pile, la file est
modifiée à ses deux bouts.

4.2 Les opérations sur une file

Les opérations primitives sur une file sont :


Defiler pour le retrait d’un élément
Enfiler pour l’ajout d’un élément. L’opération Enfiler (f, e) ajoute l’élément e à la
fin de la file f.

-30-
Ainsi, la suite des opérations Enfiler (f, A), Enfiler (f, B) et Enfiler (f, C) donnent
la file suivante :

A B C

Tete Fin

Figure 0.10 : La file résultat

Noter qu’en principe, il n’y aucune limite aux nombres d’éléments que l’on peut
ajouter dans une file.
L’opération e  Defiler (f), retire (supprime) un élément de la fin de la file et
renvoie sa valeur dans e.
Ainsi l’opération e  Defiler (f) provoque un changement d’état de la file et met
l’élément A dans e.

B C

Tete Fin

Figure 0.11 : La file résultat àprés l’appel de Defiler (f)

L'opération Defiler ne peut s’effectuer sur une file vide. Il faudra donc utiliser une
opération FileVide qui permet de tester si une file est vide ou pas.
Le résultat des opérations Enfiler (f, D) et Enfiler (f, E) est donné par la figure
précédente.

B C D E

Tete Fin

Figure 0.12 : La file résultat àprés l’appel de Enfiler (f, D) er Enfiler(f,E)

4.3 Implantation d’une file par liste chaînée

L’implantation d’une pile par une liste (simplement) chaînée est une version
simplifiée de celle d’une liste par liste chaînée.
Type File=enregistrement
ListeElem : ^liste
Finenregistrement

-31-
4.4 Les opérations sur une file

PROCEDURE InitialiserFile(p : File)


Debut
p. ListeElem nil
fin

FONCTION FileVide(p : File) : booléen


Debut
PileVide( p. ListeElem =nil)
Fin

PROCEDURE Enfiler (p : File, e : entier)


Debut
InsertQueue(p. ListeElem,e)
Fin

FONCTION Defiler (var p : file) : entier


Variable
e : entier
Debut
si (FileVide(p)) alors
ecrire ("la File est vide")
sortir
sinon
e p. ListeElem^.valeur
SuppTete(p. ListeElem)
defilere
finsi
Fin

-32-
Chapitre 5 : Les arbres

5.1 Introduction

Un arbre est par définition une structure hiérarchique. La structure d’arbre très
utilisée dans tous les domaines, parce que bien adaptée à la représentation naturelle
d’informations homogènes organisées, et d’une grande commodité et rapidité de
manipulation (REBAINE, 2,2009).

Exemples :

 Découpage d’un livre en parties, chapitres, sections, paragraphes . . .,


 hiérarchies de fichiers (systèmes d'exploitation),
 Expressions arithmétiques
 Compression de données (code Huffman)
 Décomposition syntaxique
 Tri
 Etc …

L’expression A - (B + C * (D - E)) * F se représente facilement par un arbre où
apparaît clairement la priorité des opérations:

Figure 0.13: L'arbre de l’expression

-33-
5.2 Terminologie de base et définitions

Un arbre est constitué de nœuds et de liens hiérarchiques entre ces nœuds.

Figure 0.14 : Arbre représentant la structure logique d’un livre

Chaque élément de l’arbre (nœud) possède un prédécesseur et peut avoir


plus d’un successeur. Dans la figure précédente, C1, C2 et C3 qui constituent les
chapitres du livre sont tous successeurs du nœud livre.
a. Une feuille est un nœud qui n’a pas de successeur (C3).
b. La racine est un nœud qui n’a pas de prédécesseur (Livre).
c. Nœud intérieur : Tout autre nœud a un et un seul prédécesseur. Un
nœud qui n’est ni une feuille ni la racine est appelé nœud intérieur.
d. Chemin : Si n1, n2, ..nk, sont des nœuds d’un arbre et que ni est le parent
de ni+1 pour 1 ≤ i ≤ k, cette suite est appelée chemin entre le nœud n1 et
le nœud nk . La longueur d’un chemin est le nombre de nœuds qu’il
contient L-1 (c’est en fait le nombre de segments ou arcs).
e. La profondeur d’un sommet v est la longueur du chemin qui va de la
racine à ce sommet, on écrit profond(v)
f. Le niveau p est formé des sommets de profondeur p.
g. La hauteur d’un arbre est un de plus que la longueur du plus long
chemin de la racine à une feuille. Un arbre vide est de hauteur 0.

5.3 Parcours d’arbres

Le parcours d’un arbre s’effectue dans un certain ordre pour visiter tous ses
nœuds. Les parcours les plus classiques sont les parcours infixé, préfixé et
postfixé. Ces parcours sont définis récursivement de la manière suivante :
1- Infixe (symétrique) : on parcourt d’abord le premier sous-arbre en
infixé, puis la racine, puis chacun des autres sous-arbres, en infixe.
2- Préfixe ou Pré-ordre : on parcourt d’abord la racine, puis chacun des
sous-arbres en préfixe.
3- Postfixe ou Post-ordre : on parcourt d’abord tous les sous-arbres en
postfixe, puis on parcourt la racine.

-34-
Figure 0.3 : Parcours d’un arbre

1- Infixe : L J E B F A C G D H K I
2- Préfixe : A B E J L F C D G H I K
3- Postfixe : L J E F B C G H K I D A

-35-
Chapitre 6 : Les arbres binaires

6.1 Définition

Les arbres binaires sont un cas particulier d’arbres. Ce sont des arbres où chaque
nœud possède au plus un fils gauche et au plus un fils droit. Si un nœud possède un
seul fils, il est soit un fils gauche ou un fils droit.

Exemple

Figure 0.15 : Exemple d’ arbre binaire

Un arbre binaire localement complet est un arbre binaire dont chacun des nœuds
possèdent soit 0 soit 2 fils. Ceci veut donc dire que les nœuds internes auront tous
deux fils. Dans ce type d'arbre, on peut établir une relation entre la taille de l'arbre
et le nombre de feuille. En effet, un arbre binaire localement complet de taille n aura
n+1 feuille. L'arbre suivant est localement complet :

Figure 5.2 : Arbre représentant un livre

6.1.1 Un arbre dégénéré (appelé aussi filiforme)


C’est est un arbre dont les nœuds ne possède qu'un et un seul fils. Cet arbre
est donc tout simplement une liste chaînée. Ce type d'arbre est donc à
éviter, puisqu'il n'apportera aucun avantage par rapport à une liste chaînée
simple.

6.1.2 Un arbre dégénéré


Un arbre de taille n a une hauteur égale à n+1. L'arbre suivant est un arbre
dégénéré.

-36-
Figure 5.3 : Arbre dégénéré

6.1.3 Arbre binaire complet


Est un arbre qui est localement complet et dont toutes les feuilles ont la
même profondeur. Dans ce type d'arbre, on peut exprimer le nombre de
nœuds n de l'arbre en fonction de la hauteur h : n = 2(h+1) -1.

Figure 5.4 : Arbre dégénéré

6.2 Implémentation du type arbre binaire

Dans un arbre binaire, Un nœud est composé de trois champs de types


hétérogènes, il est implémenté donc en utilisant les enregistrements de la manière
suivante :
Type nœud = Enregistrment
valeur : entier
filsg : ^ nœud
filsd : ^ nœud
FinEnregistrment

Par la suite on défini le type liste comme étant un maillon.


Type arbre = nœud

6.2.1 Déclaration d’une variable de type arbre

Une fois le type arbre est défini on peut déclarer une variable de type pointeur
sur arbre de la manière suivante :
p : ^arbre

-37-
6.2.2 Accès aux champs d’un nœud d’un arbre binaire

Si p est un pointeur sur une variable de type arbre, p^ est la variable pointée par
p. cette variable est un enregistrement, pour accéder à ses champs on utilise
l’opérateur "." .
 p^. valeur
 p^. filsg
 p^. filsd

6.3 Insertion d’un nœud d’une valeur v dans un arbre binaire

Principe

Créer un nœud d’adresse n contenant la valeur v et dont le sous arbre gauche est
g et le sous arbre droit est d.

Algorithme

Fonction CA (G : ^arbre, val : caractere, D :^arbre ): ^arbre


Variable
n : ^arbre
Debut
nnouveau(^arbre)
n^.valeurval
n^.filsgG
n^.filsdD
CAn
fin

6.4 Parcours d’un arbre binaire

6.4.1 Parcours Prefixe

PROCEDURE Prefixe(racine : ^arbre)


debut
si (racine<>Nil ) alors
ecrire(racine^.valeur)
Prefixe(racine ^.filsg)
Prefixe(racine ^. filsd)
finsi
fin

-38-
6.4.2 Parcours Infixe

PROCEDURE Infixe (racine : ^arbre)


debut
si (racine<>Nil ) alors
Infixe(racine ^.filsg)
ecrire(racine^.valeur)
Infixe(racine ^. filsd)
finsi
fin

6.4.3 Parcours Postfixé

PROCEDURE Postfixe (racine : ^arbre


debut
si (racine<>Nil ) alors
Postfixe(racine ^.filsg)
Postfixe(racine ^. filsd)
ecrire(racine^.valeur)
finsi
fin

6.5 Tester si un Nœud est une feuille

Fonction estfeuille (r : ^arbre) : entier


debut
si (r ^. filsg=Nil et r^.filsd=Nil) alors
estfeuille1
Sinon
estfeuille0
finsi
fin

6.6 Nombre de feuilles dans un arbre binaire

Fonction nbfeuille (r : ^arbre) : entier


debut
si (r=nil) alors
nbfeuille 0
Sinon
nbfeuille  estfeuille(r)+nbfeuille(r^.filsg)+nbfeuille(r^.filsd)
finsi
fin

-39-
Chapitre 7 : Les arbres binaires de recherche

7.1 Définition

Un Arbre Binaire de Recherche (ABR) A est dit de recherche ssi : si v est la valeur
portée par un nœud N de l’arbre A alors
1) v est supérieure a toutes les valeurs présentes dans le sous arbre gauche de N
2) v est inférieure a toutes les valeurs présentes dans le sous arbre droite de N

4 9

1 5

Figure 0.16: Un arbre binaire de recherche

7.2 Ajout d’une valeur dans un ABR

Ecrire la procédure Ajout qui permet d’ajouter une valeur v à un arbre binaire de
recherche donné par l’adresse de sa racine r.

-40-
7

4 9

1 5

Figure 0.17 : L’ ABR avant l’ajout de la valeur 6

4 9

1 5

Figure 0.18 : L’ ABR aprés l’ajout de la valeur 6

Principe

1) si l’arbre est vide


 Créer un Nœud n contenant la valeur V
nnouveau(^arbre)
n^.valeurv
n^.filsgNil
n^.filsdNil
 alors la racine est n
racinenouveau(^arbre)
2) sinon
 si la valeur portée par la racine est supérieure ou égale à V alors l’insertion
se fait dans le sous arbre droit
Ajout(racine^.filsd. v)
 sinon l’insertion se fait dans le sous arbre gauche
Ajout(racine^. filsg.v)

-41-
Algorithme

PROCEDURE Ajout(var r : ^arbre , v : entier )


debut
si(r=Nil) alors
rnouveau(^arbre)
r^.valeurv
r^.filsg  Nil
r^. filsd  Nil
sinon
si(v<r^.valeur)
Ajout(r^. filsg,v)
sinon
Ajout(r^. filsd,v)
finsi
finsi
fin

7.3 Recherche d’une valeur dans un ABR

Ecrire la fonction Recherche qui permet de renvoyer l’adresse du nœud qui


contient une valeur v dans un ABR donné par l’adresse de sa racine (racine).

Principe

1) si l’arbre est vide la fonction renvoie le Nil


Si (racine=Nil) alors
RechercheNil
2) Sinon, si la valeur porté par le Nœud en cours = V , en renvoie la racine
Sinon
Si (racine^.valeur=v) alors
Rechercheracine
3) Sinon, si la valeur porté par le Nœud en cours < V , la recherche se fait dans le
sous arbre gauche
Sinon
Si (racine^.valeur<v) alors
Recherche Recherche (racine^.filsg, v)
3) Sinon, la recherche se fait dans le sous arbre droite
Sinon

-42-
Recherche Recherche (racine^.filsd, v)
finsi
finsi
finsi

Algorithme

Fonction Recherche( r : ^arbre , v : entier ) : ^arbre


Debut
Si (racine=Nil ou racine^.valeur=v) alors
Rechercheracine
Sinon
Si (racine^.valeur>v) alors
Recherche Recherche (racine^.filsg)
Sinon
Recherche Recherche (racine^.filsd)
finsi
finsi
fin

7.4 Recherche du nœud père d’une valeur dans un ABR

Ecrire la fonction Pere qui permet de renvoyer l’adresse du nœud père du nœud
qui contient une valeur v dans un arbre binaire de recherche donné par l’adresse de
sa racine (racine).

Algorithme

Fonction Pere ( r : ^arbre , v : entier ) : ^arbre


Debut
Si(r=Nil ou r^.valeur=v) alors
PereNil
Sinon
Si (r^.filsg et r^.filsg^.valeur=v)alors
Perer
Sinon
Si (r^.filsd et r^.filsd^.valeur=v)alors
Perer
Sinon
Si (v<r^.valeur) alors
Pere Pere(r^.filsg,v)
Sinon
Pere Pere(r^.filsd,v)
finsi
-43-
finsi
finsi
finsi
fin

7.5 Recherche du max d’un ABR

Ecrire la fonction maxarb qui permet de renvoyer l’adresse du nœud contenant


la plus grande valeur dans un arbre binaire de recherche donné par l’adresse de sa
racine (racine).

Algorithme

Fonction maxarb ( r : ^arbre ) : entier


Debut
Si(r^.filsd=Nil)alors
maxarbr^.valeur
sinon
maxarb maxarb (r^.filsd)
finsi
fin

7.6 Suppression d’une valeur dans un ABR

Ecrire la PROCEDURE Supv qui permet de supprimer une valeur v dans un arbre
binaire de recherche donné par l’adresse de sa racine (r).

Principe :

1 ) si le nœud à supprimer n’est pas la racine

1.1) si le nœud v est une feuille,


 On cherche le nœud f qui porte la valeur v
 On cherche père de v (p)
 on met à jours les pointeurs de p
 On libère f

-44-
7

4 9

1 5

1.2) si le nœud v possède un seul fils:


 On cherche le nœud f qui porte la valeur v
 On cherche père de v (p)
 On met à jours les pointeurs de p
 On libère f

4 9

1 5

1.3) Si le nœud V possède deux fils :


 On cherche le nœud f qui porte la valeur v
 On cherche le max dans le sous arbre gauche
 On écrit max à la place de v
 On supprime max dans le sous arbre gauche

-45-
7

4 9

1 5

2 ) Si le nœud à supprimer est pas la racine

2.1) si racine est une feuille


 On libère racine
2.2) si racine possède un seul fils:
 On met à jours racine
 On libère l’ancienne racine

1 5

2.3) si la racine possède deux fils:


 On cherche le max dans le sous arbre gauche
 On remplace la valeur porté par racine par max
 on supprime max su sous arbre gauche

-46-
7

4 9

1 5

Algorithme

PROCEDURE Supv( var r :^arbre, v : entier)


variable
f,p : ^arbre
max :^entier
debut
fRecherche(r, v)
si (f=Nil) alors // v est inexistante dans l’arbre
ecrire("valeur", v, "inexistante dans l'arbre")
Sortir
finsi

Si(p=Nil) alors// on supprime la racine


si (estfeuille(f)) alors // 0 fils
Liberer(r)
sortir
finsi
si(!f->filsg et f^.filsd) alors// 1 fils a droite
rr^.filsd
Liberer(f)
sortir
finsi
si (f^.filsg et !f^.filsd) alors// 1 fils à gauche
rr^ .filsg
Liberer(f)
sortir
finsi
// 2 fils
Maxmaxarb(f^.filsg)
f^.valeurmax
Supv(f^.filsg, max)
sortir
finsi
ppere(r,v)

-47-
si(estfeuille(f)) alors // 0 fils
si(p^.filsg et p^.filsg^.valeur=v) alors
p^.filsgNIL
Liberer(f)
sortir
sinon

p^.filsdNIL
Liberer(f)
sortir
finsi
finsi
fin

-48-
Webographie

[1] https://fanfanvaconsin.files.wordpress.com/2016/04/unknown-11.jpeg

[2] https://krohne.com/fr/industries/industrie-maritime/navires-porte-conteneurs-industrie-maritime/

[3] https://www.oujdacity.net/national-article-115966-fr/waiting-dull-and-boring.html

[4] http://www.indiansamourai.com/media/00/02/19889217.jpg

-49-

Vous aimerez peut-être aussi