Chapitre V : Les Listes chainées, les Piles et les Files.
I. Généralités sur les Listes.
Le principe de base des listes est le type pointeur. Une variable de type pointeur est une
variable dont le contenu est une adresse qui peut indiquer l'emplacement en mémoire d'une autre
variable, créée dynamiquement et ayant un type de base précis.
Note : Quand une variable pointeur ne pointe sur aucun emplacement, elle doit contenir la valeur Nil (qui est
une adresse négative).
Les Structures de données linéaires
Parmi les structures de données linéaires il y a :
Les tableaux,
Les listes chaînées,
Les piles,
Les files.
Les structures de données linéaires induisent une notion de séquence entre les éléments les
composant (1er, 2ème, 3ème, suivant, dernier…).
On utilise une liste chaînée plutôt qu'un tableau lorsque l'on doit traiter des objets représentés
par des suites sur lesquelles on doit effectuer de nombreuses suppressions et de nombreux ajouts.
Les manipulations sont alors plus rapides qu'avec des tableaux.
Les files et les piles sont des listes chaînées particulières qui permettent l'ajout et la
suppression d'éléments uniquement à une des deux extrémités de la liste.
La pile est une structure de liste similaire à une pile d'assiettes où l'on pose et l'on prend
au sommet de la pile.
La file est une structure de liste similaire à une file d'attente à une caisse, le premier client
entré dans la file est le premier sorti de celle-ci (aucun resquillage n'est admis).
Conçu par : Ing. Didier Frédéryck Mbanjock Page 1 sur 24
Il existe différents types de listes chaînées :
Liste chaînée simple constituée d'éléments reliés entre eux par des pointeurs.
Liste chaînée ordonnée où l'élément suivant est plus grand que le précédent. L'insertion et
la suppression d'élément se font de façon à ce que la liste reste triée.
Liste doublement chaînée où chaque élément dispose non plus d'un mais de deux
pointeurs pointant respectivement sur l'élément précédent et l'élément suivant. Ceci permet
de lire la liste dans les deux sens, du premier vers le dernier élément ou inversement.
Liste circulaire où le dernier élément pointe sur le premier élément de la liste. S'il s'agit d'une
liste doublement chaînée alors de premier élément pointe également sur le dernier.
II. Les Listes Chainées.
A. Définition
Une liste chaînée est une structure de données dans laquelle les éléments sont rangés
linéairement. Chaque élément (dit nœud) est lié à son successeur. Il est donc impossible d'accéder
directement à un élément quelconque de la liste (sauf le premier auquel on accède via un pointeur
–généralement appelé tête ou début de liste).
Tete est le pointeur avec l’adresse du premier élément alors que chaque nœud est un enregistrement avec
une case (ici Info) pour la valeur à manipuler (ici : 12, 25, - 4 et 11) et une case (ici Suiv) de type pointeur
avec l’adresse où se trouve l’élément suivant.
Une liste chaînée simple est composée :
D’un ensemble d'éléments tels que chacun :
o Est rangé en mémoire à une certaine adresse,
o Contient une donnée (Info),
o Contient un pointeur, souvent nommé Suivant, qui contient l'adresse de l'élément suivant
dans la liste,
D’une variable, appelée Tête, contenant l'adresse du premier élément de la liste chaînée.
Le pointeur du dernier élément contient la valeur Nil. Dans le cas d'une liste vide le pointeur de la tête
contient la valeur Nil. Une liste est définie par l'adresse de son premier élément.
B. Les Opérations de base sur les listes
La création d’une liste, le parcours d’une liste ainsi que l’ajout et la suppression d’un élément sont les
principales opérations effectuées sur les listes.
1) Déclaration d’une liste
Il faut d’abord définir un type de variable pour chaque élément de la chaîne, comme suit :
Type Liste = ^Element
Element = Structure (Enregistrement)
Info : Type_standard_associé
Suivant : Liste
Fin structure
Conçu par : Ing. Didier Frédéryck Mbanjock Page 2 sur 24
Variable : Tete, P : Liste
Le type de Info dépend des valeurs contenues dans la liste : entier, chaîne de caractères, variant pour un type
quelconque…
2) Création d’une liste chainée
La création d’une liste revient à
Déclarer la tête de liste
Commencer à partir d’une liste vide (donc affecter le Nil à la tête avant de commencer)
Des ajouts (insertions) répétitifs de nœuds qui vont constituer la liste.
Pour insérer un nouvel élément il est faut d’abord réserver un espace pour ce nœud. L’opération est
possible via la procédure prédéfinie ALLOUER (p) qui permet de repérer un espace suffisant pour le nœud
(Partie donnée et pointeur de l’élément qui va suivre). L’espace trouvé est alors réservé et son adresse dans
la mémoire est sauvegardée dans la variable pointeur p.
2.3.1 Créer une liste chaînée composée de 2 éléments de type chaîne de caractères
Déclarations des types pour la liste :
Type Liste = ^Element
Element = Structure
Info : chaîne de caractères
Suivant : Liste
Fin structure
Algorithme CréationListe2Elements
Tete, P : Liste
NombreElt : entier
DEBUT
1. Tete Nil /* pour l'instant la liste est vide*/
2. Allouer(P) /* réserve un espace mémoire pour le premier élément */
3. Lire(P^.Info) /* stocke dans l'Info de l'élément pointé par P la valeur saisie */
4. P^.Suivant Nil /* il n'y a pas d'élément suivant */
5. Tete P /* le pointeur Tete pointe maintenant sur P */
/* Il faut maintenant ajouter le 2e élément, ce qui revient à insérer un élément en tête de liste */
6. Allouer(P) /* réserve un espace mémoire pour le second élément */
7. Lire(P^.Info) /* stocke dans l'Info de l'élément pointé par P la valeur saisie */
8. P^.Suivant Tete /* élément inséré en tête de liste */
9. Tete P
FIN
Ajout en début de liste
Procedure AjoutD (Var tete : P);
Variable
X: P;
Debut
Allouer (X);
Lire (X^.Info);
X^. Suiv tete;
tete X ;
Fin Procédure ;
Conçu par : Ing. Didier Frédéryck Mbanjock Page 3 sur 24
Ajout en fin de liste
Procedure AjoutF (tete : P);
Variable
X, Y: P;
Debut
Allouer (X);
Lire (X^.Info);
X^. Suiv Nil;
Y tete;
Tantque Y^.Suiv ≠ Nil Faire
Y Y^. Suiv
FinTantque;
Y^. Suiv X
Fin ;
Créer une liste chaînée composée de plusieurs éléments de type chaîne de caractères
Déclarations des types pour la liste :
Type Liste = ^Element
Element = Structure
Info : chaîne de caractères
Suivant : Liste
fin Structure
Pour créer une liste chaînée contenant un nombre d'éléments à préciser par l'utilisateur il faut
‘introduire deux variables de type Entier NombreElt et Compteur
de faire saisir la valeur de NombreElt par l'utilisateur dès le début du programme,
d'écrire une boucle Pour Compteur allant de 1 à NombreElt comprenant les instructions
6, 7, 8 et 9.
Algorithme CréationListeNombreConnu
Tete, P : Liste
NombreElt : entier
Compteur : entier
DEBUT
Lire(NombreElt)
Tete Nil
POUR Compteur DE 1 A NombreElt FAIRE
Allouer(P) /* réserve un espace mémoire pour l’élément à ajouter */
Lire(P^.Info) /* stocke dans l'Info de l'élément pointé par P la valeur saisie */
P^.Suivant Tete /* élément inséré en tête de liste */
Tete P /* le pointeur Tete pointe maintenant sur P */
FIN POUR
FIN
Conçu par : Ing. Didier Frédéryck Mbanjock Page 4 sur 24
3) Afficher les éléments d'une liste chaînée
Une liste chaînée simple ne peut être parcourue que du premier vers le dernier élément de la
liste.
L'algorithme correspond à une procédure qui reçoit la tête de liste en paramètre .
Procedure AfficherListe (Entrée P : Liste)
/* Afficher les éléments d’une liste chaînée passée en paramètre */
DEBUT
1 P Tete /* P pointe sur le premier élément de la liste*/
/* On parcourt la liste tant que l'adresse de l'élément suivant n'est pas Nil */
TANT QUE P <> NIL FAIRE /* si la liste est vide Tete est à Nil */
2 Ecrire(P^.Info) /* afficher la valeur contenue à l'adresse pointée par P */
3 P P^.Suivant /* On passe à l'élément suivant */
FIN TANT QUE
FIN Procedure
4) Rechercher une valeur donnée dans une liste chaînée ordonnée
La liste va être parcourue à partir de son premier élément (celui pointé par le pointeur de tête).
Il y’a deux conditions d’arrêt :
avoir trouvé la valeur de l'élément,
avoir atteint la fin de la liste.
L'algorithme est donné sous forme d'une procédure qui reçoit la tête de liste en paramètre. La
valeur à chercher est lue dans la procédure.
Procedure RechercherValeurListe (Entrée Tete : Liste, Val : variant)
/* Rechercher si une valeur donnée en paramètre est présente dans la liste passée en paramètre
*/
Variables locales
P : Liste /* pointeur de parcours de la liste */
Trouve : booléen /* indicateur de succès de la recherche */
DEBUT
SI Tete <> Nil ALORS /* la liste n'est pas vide on peut donc y chercher
une valeur */
P Tete
Trouve Faux
TANTQUE P <> Nil ET Non Trouve
SI P^.Info = Val ALORS /* L'élément recherché est l'élément courant */
Trouve Vrai
SINON /* L'élément courant n'est pas l'élément
recherché */
P P^.Suivant /* on passe à l'élément suivant dans la liste */
FINSI
FIN TANT QUE
SI Trouve ALORS
Ecrire (" La valeur ", Val, " est dans la liste")
Conçu par : Ing. Didier Frédéryck Mbanjock Page 5 sur 24
SINON
Ecrire (" La valeur ", Val, " n'est pas dans la liste")
FINSI
SINON
Ecrire("La liste est vide")
FINSI
FIN Procedure
5) Suppression d’un élément
On peut supprimer un élément en début de liste (le second deviendra le nouveau premier), en
fin de liste (l’avant dernier deviendra le dernier) ou encore en milieu de liste (entre deux
éléments)
On peut supprimer un élément logiquement (il ne fera plus partie de la liste mais il existera
toujours et son adresse sera retournée dans un paramètre pour servir dans un autre traitement)
ou le supprimer réellement (suppression physique) en libérant son espace mémoire en utilisant
la procédure prédéfinie Liberer (p) qui permet de rendre au système d’exploitation le contrôle
sur l’espace dont l’adresse est "p" occupé par le nœud supprimé. Une suppression physique
est donc une suppression logique suivie d’un "Liberer".
Supprimer le premier élément d'une liste chaînée
Il y a deux actions, dans cet ordre, à réaliser :
faire pointer la tête de liste sur le deuxième
élément de la liste,
libérer l'espace mémoire occupé par l'élément
supprimé.
Il est nécessaire de déclarer un pointeur local qui va
pointer sur l'élément à supprimer, et permettre de libérer l'espace qu'il occupait.
Procedure SupprimerPremierElement (Entrée/Sortie Tete : Liste)
/* Supprime le premier élément de la liste dont le pointeur de tête est passé en paramètre */
Variables locales
P : Liste /* pointeur sur l'élément à supprimer */
DEBUT
SI Tete <> Nil ALORS /* la liste n'est pas vide on peut donc supprimer le premier élément */
P Tete /* P pointe sur le 1er élément de la liste */
Tete P^.Suivant /* la tête de liste doit pointer sur le deuxième 'élément */
Desallouer(P) /* ou Liberer(P) libération de l'espace mémoire qu'occupait le premier
élément */
SINON
Ecrire("La liste est vide")
FINSI
FIN Procedure
Supprimer d'une liste chaînée un élément portant une valeur donnée
Conçu par : Ing. Didier Frédéryck Mbanjock Page 6 sur 24
Il faut :
Traiter à part la suppression du premier élément car il faut modifier le pointeur de tête,
Trouver l'adresse P de l'élément à supprimer,
Sauvegarder l'adresse Prec de l'élément précédant l'élément pointé par P pour connaître
l'adresse de l'élément précédant l'élément à supprimer, puis faire pointer l'élément précédent
sur l'élément suivant l'élément à supprimer,
Libérer l'espace mémoire occupé par l'élément supprimé.
L'exemple considère que l'on souhaite supprimer l'élément contenant la valeur "liste" de la liste ci-
dessus.
Procedure SupprimerElement (Entrée/Sortie Tete : Liste, Val : variant)
/* Supprime l'élément dont la valeur est passée en paramètre */
Variables locales
P : Liste /* pointeur sur l'élément à supprimer */
Prec : Liste /* pointeur sur l'élément précédant l'élément à supprimer */
Trouvé : Liste /* indique si l'élément à supprimer a été trouvé */
DEBUT
SI Tete <> Nil ALORS /* la liste n'est pas vide on peut donc y chercher une valeur à
supprimer */
SI Tete^.info = Val ALORS /* l'élément à supprimer est le premier */
P Tete
Tete Tete^Suivant
Desallouer(P)
SINON /* l'élément à supprimer n'est pas le premier */
Trouve Faux
Prec Tete /* pointeur précédent */
P Tete^.Suivant /* pointeur courant */
TANTQUE P <> Nil ET Non Trouve
SI P^.Info = Val ALORS /* L'élément recherché est l'élément courant */
Trouve Vrai
SINON /* L'élément courant n'est pas l'élément cherché */
Prec P /* on garde la position du précédent */
P^ P^.Suivant /* on passe à l'élément suivant dans la liste */
FINSI
FIN TANT QUE
SI Trouve ALORS
Prec^.Suivant P^.Suivant /* on "saute" l'élément à supprimer "/
Desallouer(P)
SINON
Ecrire ("La valeur ", Val, " n'est pas dans la liste")
Conçu par : Ing. Didier Frédéryck Mbanjock Page 7 sur 24
FINSI
FINSI
SINON
Ecrire("La liste est vide")
FINSI
FIN Procedure
Suppression en fin de liste
a. Suppression logique en fin :
Procedure SupprimeF (Var tete, X : P);
Variable
Y: P;
Debut
Si tete = Nil Alors
X Nil;
Sinon
X tete;
Y X ;
Tantque X^.Suiv ≠ Nil Faire
Y X ;
X X^. Suiv
FinTantque;
Si Y = tete Alors
Tete Nil
Sinon
Y^. Suiv Nil
FinSi
FinSi
Fin Procedure.
b. Suppression physique en fin :
Ajouter l’instruction « Liberer (X) » avant la fin
Procedure SupprimeF (tete: P);
Variable
X, Y: P;
Debut
X tete;
Y X ;
Tantque X^.Suiv ≠ Nil Faire
Y X ;
X X^. Suiv
FinTantque;
Conçu par : Ing. Didier Frédéryck Mbanjock Page 8 sur 24
Y^. Suiv Nil ;
Liberer (X)
Fin Procedure ;
III. Variantes de listes chaînées
A. Liste simplement chaînée
Une liste est dite simplement chaînée si chacun de ses nœuds contient une partie
donnée (info) et l’adresse du nœud qui le suit. Les opérations précédentes sont toutes
valides sur ce type.
B. Liste doublement chaînée
Une liste est dite doublement chaînée si chaque nœud de cette liste contient une
partie donnée, l’adresse du nœud qui la suit et l’adresse du nœud qui la précède
(donc simplement chaînée avec en plus un chainage arrière).
N.B Il n’y a pas d’élément avant le premier nœud, la valeur du pointeur Prec = Nil.
La déclaration des listes doublement chaînées nécessite donc un pointeur vers un
enregistrement de 3 cases :
Type
PX = ^ Element ;
Element = Enregistrement
Prec : ^ Element;
Info : Type-C ;
Suiv : ^ Element
Fin ;
L’intérêt de ce type de listes est le déplacement d’un élément vers son prédécesseur en un seul
pas. Il est cependant nécessaire d’établir des changements dans les opérations de base à la fin
de garantir cette flexibilité.
Exemples :
Conçu par : Ing. Didier Frédéryck Mbanjock Page 9 sur 24
- Ajout Début
Procedure AjoutD (Var tete : PX);
Variable
X: PX;
Debut
Allouer (X);
X^. Prec Nil ;
Lire (X^.Info);
Tete^.Prec X ;
X^. Suiv tete;
tete X ;
Fin ;
Il fallait
o Mettre le Nil dans la case précédent (Prec) du nouveau nœud car ce dernier
deviendra le premier et donc n’aura aucun élément avant lui.
o Remplacer le Prec de l’actuel premier élément (Nil) par l’adresse du nouveau
nœud car ce dernier sera placé avant lui.
Suppression (On suppose que l’adresse de l’élément à supprimer existe réellement)
Procedure Supprime (Var tete, A : PX);
Variable A
Y: PX;
Debut
Si A = tete Alors
Debut
A^.Suiv^.Prec Nil ;
Tete A^.Suiv /*cas suppression au début*/
Fin
Sinon
Si A^.Suiv = Nil Alors
A^.Prec^.Suiv Nil /*cas suppression à la fin*/
Sinon
A^.Suiv^.Prec A^.Prec ; /*cas suppression au milieu*/
A^.Prec^.Suiv A^.Suiv;
Liberer (A) ;
FinSi
Fin ;
Conçu par : Ing. Didier Frédéryck Mbanjock Page 10 sur 24
C. La Liste circulaire
Une liste est dite circulaire si le dernier nœud de cette liste nous remet au premier nœud
de cette liste ; c.-à-d. que la case pointeur du dernier élément ne contient pas Nil mais l’adresse
du premier élément (tete).
L’absence du Nil dans ce type de liste (sauf le cas d’une liste vide) implique des conditions
d’arrêt en rapport avec la tête de liste.
Il s’avère alors nécessaire de ne pas
traiter tous les "n" éléments de la liste
dans la même boucle mais plutôt de
traiter "n-1" éléments ensemble et de répéter le traitement pour le nœud qui n’a pas été traité
(ou encore utiliser la boucle répéter au lieu du Tant que).
N.B. : L’élément à traiter seul peut être le premier de liste (et avoir une boucle de traitement
du 2ème au dernier élément) ou le dernier nœud de la liste (traiter du 1er à l’avant dernier
élément dans la boucle puis réécrire le traitement pour le dernier nœud.)
D. Liste circulaire doublement chaînée
Cette variation regroupe les caractéristiques des listes doublement chaînées (présence du
Prec) et des listes circulaires l’absence du Nil (car le Suiv du dernier nœud renvoi vers le
premier élément et le Prec du premier nœud renvoi vers le dernier élément.)
Exemple :
Ecrire une fonction qui calcule le nombre de zéro dans une liste d’entiers. La liste est supposée
déjà lue.
Corrigé pour liste simplement chaînée :
Fonction calcul-SChai (L : P) : entier ;
Variable
Pt : P ;
Co : Entier ;
Debut
Co 0 ;
Pt L ;
Tantque Pt ≠ Nil Faire
Si Pt^.Info = 0 Alors
Co Co + 1
Conçu par : Ing. Didier Frédéryck Mbanjock Page 11 sur 24
FinSi ;
Pt Pt^. Suiv
FinTantque ;
Calcul Co ;
Fin ;
Corrigé pour liste circulaire :
Fonction calcul-DChai1 (L : PX) : entier ;
Variable
Pt : PX ;
Co : Entier ;
Debut
Co 0 ;
Pt L ;
Tantque Pt^. Suiv ≠ L Faire /* Traitement des N-1 premiers noeuds ensemble*/
Si Pt^.Info = 0 Alors
Co Co + 1
FinSi ;
Pt Pt^. Suiv
FinTantque ;
Si Pt^.Info = 0 Alors /* Traitement du dernier noeud seul*/
Co Co + 1
FinSi ;
Calcul Co ;
Fin ;
IV. Les piles et les files
Les files et les piles sont des listes chaînées particulières qui permettent l'ajout et la
suppression d'éléments uniquement à une des deux extrémités de la liste.
La pile est une structure de liste similaire à une pile d'assiettes où l'on pose et l'on
prend au sommet de la pile.
La file est une structure de liste similaire à une file d'attente à une caisse, le premier
client entré dans la file est le premier sorti de celle-ci (aucun resquillage n'est admis).
Conçu par : Ing. Didier Frédéryck Mbanjock Page 12 sur 24
A. La Pile
Une pile est un ensemble de valeurs ne
permettant des insertions ou des suppressions qu’a
une seule extrémité, appelée sommet de la pile.
Empiler un objet sur une pile P consiste à insérer cet
objet au sommet de P (dans la pile d’assiettes une
nouvelle assiette ne peut être ajoutée qu’au-dessus
de celle qui se trouve au sommet) ;
Dépiler un objet de P consiste à supprimer de P
l'objet placé au sommet (dans la pile d’assiettes
seule peut être retirée celle qui se trouve au
sommet). L'objet dépilé est retourné comme résultat
du traitement.
La manipulation d’une pile revient à l’appel de fonctions et procédures dites de bases définies
une seule fois et utilisées autant de fois qu’il est nécessaire.
Ces sous-algorithmes sont :
- Init_Pile : permet d’initialiser une pile à vide lors de sa création ;
- Pile_vide : pour vérifier si une pile est vide ou non et savoir alors s’il reste des
valeurs à traiter ou non ;
- Pile_pleine : pour vérifier s’il est possible de rajouter ou non un nouvel élément
(utilisée dans le seul cas des piles statiques) ;
- Empiler : permet d’ajouter une nouvelle valeur (envoyé en paramètre par
l’appelant) à la pile (au-dessus du sommet et dans le cas d’une pile non pleine)
;
- Depiler : permet de supprimer une valeur (se trouvant au sommet de la pile) et
de la renvoyer en paramètre. Cette opération n’est possible que si la file n’est
pas vide.
1. La Pile statique
Une pile statique est un enregistrement à 2 cases : un tableau à hauteur maximale
prévisible et un indice entier qui pointe la dernière valeur ajoutée à la pile (sommet).
Déclaration
Constante
N = …. ; /* taille du tableau*/
Type
Tab = Tableau de N Type_C ; /* Type_C est le type des données enregistrées
dans la pile*/
Pile = Enregistrement
Conçu par : Ing. Didier Frédéryck Mbanjock Page 13 sur 24
T : Tab ; N
Sommet : Entier
Fin ;
Initialisation d’une pile
Procedure Init_Pile (Var P : Pile) ;
Debut
P. Sommet 0
Fin ;
Vérification de pile vide
Fonction Pile_vide (P : Pile) : Booleen ;
Debut
Si P. Sommet = 0 Alors
Pile_vide vrai
Sinon
Pile_vide faux
FinSi ;
Fin ;
Vérification de pile pleine
Fonction Pile_pleine (P : Pile) : Booleen ;
Debut
Si P. Sommet = N Alors
Pile_pleine vrai
Sinon
Pile_pleine faux
FinSi ;
Fin ;
Ajout d’une nouvelle valeur à une pile
Procedure Empiler (Var P : Pile ; X : Type_C) ;
Debut
Si Pile_pleine (P) Alors
Ecrire('Impossible la pile est pleine')
Sinon
Debut
P. Sommet P. Sommet + 1 ;
P.T (P. Sommet) X ;
Fin
FinSi ;
Conçu par : Ing. Didier Frédéryck Mbanjock Page 14 sur 24
Fin ;
Suppression d’une valeur de la pile
Procedure Depiler (Var P : Pile, X : Type_C) ;
Debut
Si Pile_vide (P) Alors
Ecrire('Impossible la pile est vide')
Sinon
Debut
X P.T (P. Sommet) ;
P. Sommet P. Sommet - 1 ;
Fin
FinSi ;
Fin ;
2. La Pile dynamique
Une pile dynamique est une liste à la quel on attache un pointeur sommet. C’est un
enregistrement à une seule case : pointeur qui pointe la dernière valeur traitée dans la liste
(sommet).
Déclaration d’une pile dynamique
Type
Liste = ^Elem
Elem = Enregistrement
Info : Type_C ;
Suiv : ^Elem
Fin ;
PileD = Enregistrement
Sommet : Liste
Fin ;
Initialisation d’une pile dynamique
Procedure Init_PileD (P : PileD) ;
Debut
P. Sommet Nil
Fin
Vérification de pile vide dynamique
Fonction Pile_videD (P : PileD) : Booleen ;
Debut
Conçu par : Ing. Didier Frédéryck Mbanjock Page 15 sur 24
Si P. Sommet = Nil Alors
Pile_videD vrai
Sinon
Pile_videD faux
FinSi ;
Fin ;
Ajout d’une nouvelle valeur à une pile dynamique
Procedure EmpilerD (Var P : PileD ; X : Type_C) ;
Variable
Pt : Liste ;
Debut
Allouer (Pt) ;
Pt^.Info X ;
Pt^. Suiv P. Sommet ;
P. Sommet Pt ;
Fin ;
Note : L‘ajout d’une valeur à une pile dynamique revient à une insertion en début de liste si
l’on considère que le sommet est la tête de la liste.
Suppression d’une valeur de la pile dynamique
La suppression d’une valeur dans une pile dynamique revient à effectuer une suppression
physique d’un nœud (le premier de liste) et à récupérer dans un paramètre, passé par variable,
la donnée enregistrée.
Procedure DepilerD (Var P : Pile, X : Type_C) ;
Variable
Pt : Liste ;
Debut
Si Pile_videD (P) Alors
Ecrire('Impossible la pile est vide')
Sinon
Debut
Pt P. Sommet ;
X [Link]^.Info ;
P. Sommet P. Sommet^.Suiv ;
Liberer (Pt)
Fin
FinSi ;
Fin ;
Conçu par : Ing. Didier Frédéryck Mbanjock Page 16 sur 24
B. La File
Une file est un ensemble de valeurs qui a un début (Debut) et une fin (Queue).
Enfiler un objet sur une file F consiste à insérer cet objet à la fin de la file F (dans la file
d’attente un nouvel arrivant se met à la queue c.-à-d., après la personne arrivée juste avant lui)
;
Défiler un objet de F consiste à supprimer de F l'objet placé en début de file (dans la file
d’attente seule peut être servie la personne qui se trouve en début de file). L'objet défilé est
retourné comme résultat du traitement.
Une file sert essentiellement à stocker des
données qui doivent être traitées selon leur ordre
d’arrivée. L’exemple le plus connu est celui de
l’impression de documents reçus par une imprimante
qui imprime le premier document arrivé et termine par
le dernier. Ce qui fait que les objets quittent la pile dans
l'ordre de leur ordre d'arrivée. Pour cette raison, une file
est aussi appelée structure FIFO (First In, First Out) ou (premier arrivé, premier sorti)
Une file est un enregistrement avec :
- Une structure de données pour enregistrées les valeurs (elle peut être statique ou
dynamique)
- Une variable Debut qui indique le premier élément de la file.
- Une variable Queue qui indique le dernier élément de la file.
- La manipulation d’une file revient à l’appel de fonctions et procédures dites de bases
définies une seule fois et utilisées autant de fois qu’il est nécessaire.
Ces sous-algorithmes sont :
- Init_File : permet d’initialiser une file à vide lors de sa création ;
- File_vide : pour vérifier si une file est vide ou non et savoir alors s’il reste des
valeurs à traiter ou non ;
- File_pleine : pour vérifier s’il est possible de rajouter ou non un nouvel élément
(utilisée dans le seul cas des files statiques) ;
- Enfiler : permet d’ajouter une nouvelle valeur (envoyé en paramètre par
l’appelant) à la file (après le dernier élément de la file qui se trouve au niveau
de sa queue et dans le cas d’une file non pleine) ;
- Defiler : permet de supprimer une valeur (se trouvant au début de la file) et de
la renvoyer en paramètre. Cette opération n’est possible que si la file n’est pas
vide.
Conçu par : Ing. Didier Frédéryck Mbanjock Page 17 sur 24
1. File statique
Une file statique est un enregistrement à 3 cases : un tableau à hauteur maximale
prévisible, un indice entier qui pointe le premier élément insérer dans la file (Debut)
et un deuxième indice entier qui pointe la dernière valeur ajoutée (Queue).
Déclaration
Constante
N = …. ; /* taille du tableau*/
Type
Tab = Tableau de N Type_C ; /* Type_C est le type des données enregistrées
dans la pile*/
File = Enregistrement
T : Tab ;
Debut, Queue : Entier
Fin ;
Initialisation d’une file
Procedure Init_File (Var F : File) ;
Debut
F. Debut 1 ;
F. Queue 0
Fin ;
Vérification de File vide
Fonction File_vide (F : File) : Booleen ;
Debut
Si F. Debut > F. Queue Alors
File_vide vrai
Sinon
File_vide faux
FinSi ;
Fin ;
Vérification de File pleine
Fonction File_pleine (F : File) : Booleen ;
Debut
Si (F. Queue = N) et ([Link] < F. Queue) Alors
File_pleine vrai
Sinon
Conçu par : Ing. Didier Frédéryck Mbanjock Page 18 sur 24
File_pleine faux
FinSi ;
Fin ;
Ajout d’une nouvelle valeur à une File
Procedure Enfiler (Var F : File ; X : Type_C) ;
Debut
Si File_pleine (F) Alors
Ecrire('Impossible la file est pleine')
Sinon
Debut
F. Queue F. Queue + 1 ;
F.T (F. Queue) X ;
Fin
FinSi ;
Fin ;
Suppression d’une valeur de la File
Procedure DeFiler (Var F : File, X : Type_C) ;
Debut
Si File_vide (F) Alors
Ecrire('Impossible la File est vide')
Sinon
Debut
X F.T (F. Debut) ;
F. Debut F. Debut + 1 ;
Fin
FinSi ;
Fin ;
1) File dynamique
Une File dynamique est une liste à la quel on attache deux (2) pointeurs Debut
et Queue. C’est un enregistrement à deux cases : pointeur qui pointe le premier
élément de la liste (Debut) et un autre qui pointe la dernière valeur ajoutée dans la
liste (Queue).
Déclaration d’une file dynamique
Type
Liste = ^Elem
Elem = Enregistrement FileD
Conçu par : Ing. Didier Frédéryck Mbanjock Page 19 sur 24
Info : Type_C ;
Suiv : ^Elem
Fin ;
FileD = Enregistrement
Sommet, Queue : Liste
Fin ;
Initialisation d’une file dynamique
Procedure Init_FileD (F : FileD) ;
Debut
F. Debut Nil ;
F. Queue Nil
Fin ;
Vérification de File vide dynamique
Fonction File_videD (F : FileD) : Booleen ;
Debut
Si F. Queue = Nil Alors
File_videD vrai
Sinon
File_videD faux
FinSi ;
Fin ;
Ajout d’une nouvelle valeur à une file dynamique
L‘ajout d’une valeur à une File dynamique revient à une insertion à la fin de liste
avec l’adresse du dernier élément dans Queue. Le cas d’un enfiler sur file vide
nécessite l’initialisation du Debut à l’adresse du nouveau noeud.
Procedure EnfilerD (Var F : FileD ; X : Type_C) ;
Variable
Pt : Liste ;
Debut
Allouer (Pt) ;
Pt^.Info X ;
Pt^. Suiv Nil ;
Si File_videD (F) Alors
F. Debut Pt
Sinon
F. Queue^.Suiv Pt
FinSi ;
F. Queue Pt ;
Fin ;
Conçu par : Ing. Didier Frédéryck Mbanjock Page 20 sur 24
Suppression d’une valeur de la file dynamique
La suppression d’une valeur dans une file dynamique revient à effectuer une
suppression physique d’un noeud (le premier de liste) et à récupérer dans un
paramètre, passé par variable, la donnée enregistrée.
Procedure DefilerD (Var F: FileD, X : Type_C) ;
Variable
Pt : Liste ;
Debut
Si File_videD (F) Alors
Ecrire('Impossible la file est vide')
Sinon
Debut
Pt F. Debut ;
X [Link]^.Info ;
F. Debut F. Debut^.Suiv ;
Si F. Debut = Nil Alors
F. Queue Nil
FinSi /* si debut devient Nil cela veut dire que la file a été vidée et Queue
doit devenir Nil*/
Liberer (Pt)
Fin
FinSi ;
Fin ;
Exercices d’Application sur Piles et Files
Dans les exercices avec piles et files il est suffit de faire appel aux sous algorithmes de base
définis dans les sections précédentes.
Exercice 1 :
Ecrire une procédure afficher (F1) qui affiche tous les éléments d’une file de mots et une autre
défilerJusqua (F1, elt) qui défile la file jusqu'à l'élément elt. L'élément elt n'est pas défilé. Si
Procedure afficher (F1 : File) ;
Variable
Mot : Chaine de caractere ;
Debut
Tantque Non (File_vide (F1)) Faire
Debut
Conçu par : Ing. Didier Frédéryck Mbanjock Page 21 sur 24
Defiler (F1, Mot) ;
Ecrire (Mot)
Fin ;
FinTantque
Fin ; l'élément n'appartient pas à la file, alors la fonction défile toute la file.
Si l’on considère que la file est dynamique il suffit de faire appel aux sous-algorithmes de base
des files dynamiques comme suit :
Procedure afficher (F1 : FileD) ;
Variable
Mot : Chaine de caractere ;
Debut
Tantque Non (File_videD (F1)) Faire
Debut
DefilerD (F1, Mot) ;
Ecrire (Mot)
Fin ;
FinTantque
Fin ;
Procedure défilerJusqua (Var F1 : File ; elt : chaine de caractere) ;
Variable
Mot : Chaine de caractere ;
B : Booleen ;
Debut
B Vrai ;
Tantque (B ) et Non (File_vide (F1)) Faire
Debut
Defiler (F1, Mot) ;
Si Mot = elt Alors
Debut
B Faux ;
Enfiler (F1, elt)
Fin
FinSi
FinTant Que ;
Fin ;
Conçu par : Ing. Didier Frédéryck Mbanjock Page 22 sur 24
Exercice 2 :
Ecrire une procédure qui inverse une pile P1de réels. Doit-on utiliser une pile ou une file ?
Pour inverser une pile on aurait besoin d’utiliser une file où l’on enfile ce qui a été dépilé puis
empilant à partir de la file les éléments seront installés dans l’ordre inverse.
Procedure inver (var P1 : Pile);
Variable
Y: Reel;
F: File;
Debut
Init_File (F);
Tantque Non (Pile_vide (P1)) Faire
Debut
Depiler (P1, Y) ;
Enfiler (F, Y) ;
Fin ;
FinTantque ;
Init_Pile (P1);
Tantque Non (File_vide (F)) Faire
Debut
Defiler (F, Y) ;
Empiler (P1, Y)
Fin ;
FinTantque
Fin ;
Exercice 3 :
On se donne une pile P1 contenant des entiers positifs.
Ecrire un algorithme pour déplacer les entiers de P1 dans une pile P2 de façon à avoir dans P2
tous les nombres pairs en dessus des nombres impairs en gardant l’ordre d’apparition des
nombre pairs et en inversant l’ordre d’apparition des nombres impairs. Au retour à l’algorithme
appelant on doit retrouver P1 initiale.
Procedure Pair (P1 : Pile; Var P2: Pile);
Variable
Y: Entier;
P3: Pile;
Debut
Conçu par : Ing. Didier Frédéryck Mbanjock Page 23 sur 24
Init_Pile (P2);
Init_Pile (P3);
Tantque Non (Pile_vide (P1)) Faire
Debut
Depiler (P1, Y) ;
Si Y Mod 2 = 0 Alors
Empiler (P3, Y)
Sinon
Empliler (P2, Y)
FinSi ;
Fin
FinTantque ;
Tantque Non (Pile_vide (P3)) Faire
Debut
Depiler (P3, Y) ;
Empiler (P2, Y)
Fin ;
FinTantque
Fin ;
Conçu par : Ing. Didier Frédéryck Mbanjock Page 24 sur 24