Vous êtes sur la page 1sur 14

Chapitre 4 : Les Piles et Les Files Université de Batna 2 Algorithmique et structures de données

Chapitre 4 : Les Piles et Les Files


Introduction générale :
Les piles et les files sont deux structures de données très utilisé dans la pratique, elles servent essentiellement à stocker de
façon temporaire des éléments sur lesquelles, on effectue un grand nombre d’insertion et de suppression.

Il n'y a pas de structures spécifiques prévues dans les langages de programmation pour les piles ou files. Il faut donc les créer
de toute pièce sachant que la représentation en mémoire de ces structures de données peut être, selon le besoin, statique
(utilisation des tableaux) ou dynamique (utilisation des listes).

1. Les piles (stack)


Une pile est une structure de donnée qui stocke de manière ordonnée des éléments, mais rend accessible uniquement un
seul d'entre eux, appelé le sommet de la pile.

Quand on ajoute un élément, celui-ci devient le sommet de la pile, c'est-à-dire le seul élément accessible.

Quant on retire un élément de la pile, on retire toujours le sommet è le dernier élément ajouté avant (avant le sommet) lui
devient alors le sommet de la pile.

Résumé
Pour résumer, le dernier élément ajouté dans la pile est le premier élément à en être retiré. Cette structure est
également appelée une liste LIFO (Last In, First Out).

1.1. Opérations autorisées :


Les opérations autorisées avec une pile sont :
Ø Initialiser une pile
Ø Empiler « insérer », toujours au sommet, et jusqu’à la limite de la mémoire.
Ø Dépiler « retirer », toujours au sommet, si la pile n’est pas vide.
Ø Consulter le dernier élément de la pile (le sommet de la pile), sans le faire dépiler.
Ø Vérifier si la pile est vide ou non.

On associe à une pile les termes de :


Ø PUSH pour empiler c'est-à-dire ajouter un élément.
Ø POP pour dépiler c'est-à-dire supprimer un élément.

1.2. Utilisation des piles :


1.2.1. Dans un navigateur web :
Une pile sert à mémoriser les pages Web visitées. L’adresse de chaque nouvelle page visitée est empilée et
l’utilisateur dépile l’adresse de la page précédente en cliquant le bouton "Afficher la page précédente".

1.2.2. Annulation des opérations :


La fonction "Annuler la frappe" d’un traitement de texte mémorise les modifications apportées au texte dans une
pile.

1.2.3. Gestion des appels dans l’exécution des programmes (fonctions et procédures):

La notion de pile est très utilisée en programmation et beaucoup plus dans l’appel des procédures et fonctions.

M. bada 1
Chapitre 4 : Les Piles et Les Files Université de Batna 2 Algorithmique et structures de données
Ex : l’appel récursif (fonction factorielle)

a) Etapes d’empilements (insertions ) :

A= Fact (4) ; è Fact = 4 * Fact (3)

Lors de l’appel, le compilateur réservera 2 cases (une pour le paramètre N de la fonction, et une pour la
variable de retour Fact ) è on dit que le compilateur empile les 2 variables.

Fact (4) , Sommet Fact ???? = 4* fact (3)


N 4

L’appel fact (4) ne pourra pas terminer l’exécution, car fact (4) dépend de fact (3) è il faut appeler fact (3)
avant de terminer fact (4).

Quand on fait un appel à fact (3), il faut empiler encore 2 nouvelles cases (N= 3 , et fact = 3 *fact (2) )

Fact (3)
fact ???? = 3 * fact (2)
Sommet N 3
Fact ???? = 4* fact (3) Empiler
Fact ???? = 4* fact (3)
N 4 N 4

L’appel récursif (resp : l’empilement) continuera jusqu'à fact (0) = 1, qui est une valeur déterminé « la
condition d’arrêt »

Fact Fact (0) = 1


Sommet « valeur déterminée »
N 0
Fact ????= 1 * fact (0)
N 1
Fact ???? = 2 * fact (1)
N 2
fact ???? = 3 * fact (2)
N 3
Fact ???? = 4* fact (3)
N 4

M. bada 2
Chapitre 4 : Les Piles et Les Files Université de Batna 2 Algorithmique et structures de données
b) Etapes de dépilements (suppression) :

Une fois fact (0) =1 se termine l’exécution, il faut retourner le résultat à fact (1) « qui à fait l’appel fact(0) ».

Maintenant, on aura pas besoin de fact (0), et il faut bien libérer l’espace occuper par cet fonction (appel).
Ceci consiste à dépiler les deux cases qui se trouvent dans le sommet de la pile

Fact 1= 1*1 Dépiler


Sommet N 1
Fact ???? = 2 * fact (1)
N 2
fact ???? = 3 * fact (2)
N 3
Fact ???? = 4* fact (3)
N 4

Fact 1= 1*1 fact 6=3*2


N 1 N 3
Fact ???? = 2 * fact (1) Fact ???? = 4* fact (3)
N 2 Fact 2=2*1 N 4
fact ???? = 3 * fact (2) N 2
N 3 fact ???? = 3 * fact (2)
Fact ???? = 4* fact (3) N 3
N 4 Fact ???? = 4* fact (3)
N 4

Fact 24 = 4* 6
N 4

M. bada 3
Chapitre 4 : Les Piles et Les Files Université de Batna 2 Algorithmique et structures de données
1.3. Représentation d’une pile :
Il n'y a pas de structures spécifiques prévues dans les langages de programmation pour les piles ou files. Il faut donc
les créer de toute pièce sachant que la représentation en mémoire de ces structures de données peut être, selon le
besoin, statique (utilisation des tableaux) ou dynamique (utilisation des listes).

1.3.1. Représentation statique :

Il existe plusieurs manières pour représenter une Pile statique. En adoptant dans ce cours une représentation qui
évite le décalage des cases à chaque insertion ou suppression. Cependant cette représentation présente d’autres
inconvénients.

Une pile statique est un enregistrement à 2 cases :


• un tableau à hauteur maximale prévisible (généralement les éléments sont des structures de données :
étudiant, etc...)
• un indice entier qui pointe la dernière valeur ajoutée à la pile (sommet).

struct Pile {
TypeElement Tab [100] ;
int Sommet ;
};
typedef struct Pile Pile;

Note : Les données enregistrées dans la pile peuvent être des entiers, des réels, des caractères, des chaînes de
caractères, des booléens (n’existe pas en C), des tableaux, des pointeurs de listes ou encore des piles ou files.

1.3.1.1. Initialisation d’une pile statique :


Permet d’initialiser une pile à vide lors de sa création

Init_pile (Pile * P) {

(*P).Sommet = -1 ;

}
.....l’appel par adresse ......
Pile p1 ;
Init_pile (&p1) ;

1.3.1.2. Vérification si la pile est vide :


Pour vérifier si une pile est vide ou non et savoir alors s’il reste des valeurs à traiter ou non

int Pile_vide (Pile P)


{
if ( P.Sommet ==-1)
{
return 1 ;
}else
{
return 0 ;
}
}

M. bada 4
Chapitre 4 : Les Piles et Les Files Université de Batna 2 Algorithmique et structures de données
1.3.1.3. Vérification si la pile est pleine :
Pour vérifier s’il est possible de rajouter ou non un nouveau élément (utilisée dans le seul cas des piles statiques)

int Pile_Plein (Pile P)


{
if ( P.Sommet ==MAX-1)
{
return 1 ;
}else
{
return 0 ;
}
}

1.3.1.4. Empiler un élément : (Le passage de la pile doit être par Adresse)

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) ;

void push ( Pile* P , TypeElement e)


{
if ( Pile_Plein (*P) )
{ printf (" Impossible, la pile est pleine ") ;
}else
{ (*P).Sommet = (*P).Sommet + 1 ; //incrémenter le sommet
(*P).Tab [ (*P).Sommet ] = e ; // insérer le nouvel élément dans le sommet
}
}

.....l’appel par adresse ......


TypeElement x ;
// la lecture de x ;
Pile p1 ;
Init_pile (&p1) ;
push (&p1, x) ;

1.3.1.5. Dépiler un élément :

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

TypeElement depiler ( Pile *P)


{ TypeElement x ;
if ((*P).Sommet>=0 ){
x= (*P).Tab [ (*P).Sommet ] ;
(*P).Sommet = (*P).Sommet - 1 ;
return x ;
}
}

....l’appel par adresse ......


......
TypeElement x ;
x= depiler (&p1);

M. bada 5
Chapitre 4 : Les Piles et Les Files Université de Batna 2 Algorithmique et structures de données

1.3.2. Représentation dynamique :

Du point de vue implémentation, il n’y a aucune différence entre une struct Element {
Pile dynamique et une liste chainée. La seule différence réside dans int info;
les opérations qu’on effectue sur la pile. Element* suivant;
};
Sur une Pile, l’ajout et la suppression d’un élément ne doivent
s’opérer qu’au début de la pile (Tête) typedef Element* pile;

1.3.2.1. Initialisation d’une pile Dynamique:

pile Init_pile ( ){

return NULL;

.......................................................
L’appel : pile p1;
p1= Init_pile();
.......................................................

1.3.2.2. Tester si la pile est vide :

int Pile_vide (pile P){

if (P==NULL){
return 1;
}else{
return 0;
}
}

1.3.2.3. Empiler un élément : (ex : pile des entiers)


Empiler un élément revient à faire une insertion en tête dans la liste chaînée.

1ere solution :
Passage de la pile par valeur : Dans ce cas, on aura une nouvelle pile :

pile push (pile P, int x) {

//allocation d’espace memoire pour le nouvel element


Element* e;
e= (Element*) malloc (sizeof (Element) );

//copier la valeur de x dans le nouvel element


(*e).info = x;

//établir les 2 liaisons


(*e).suivant = P;
P=e;

//retourner la pile
return P;
}
...............................................................................................................................................
pile p1;
p1= Init_pile();

p1= push (p1,23);


p1= push (p1,13);
p1= push (p1,44);
...............................................................................................................................................

M. bada 6
Chapitre 4 : Les Piles et Les Files Université de Batna 2 Algorithmique et structures de données

2eme solution :
Dans ce cas, on envoie l’adresse de la pile (appel par adresse) è ajouter étoile avant P partout dans la
fonction.

push2 (pile *P, int x) {

//allocation d’espace mémoire pour le nouvel élément


Element* e;
e= (Element*) malloc (sizeof (Element) );

//copier la valeur de x dans le nouvel élément


(*e).info = x;

//établir les 2 liaisons


(*e).suivant = *P;
*P=e;

//pas de retour ç ç ç car l’appel est par adresse

...............................................................................................................................................
pile p1;
p1= Init_pile();

push2 (&p1,23);
push2 (&p1,13);
push2 (&p1,44);
...............................................................................................................................................

1.3.2.4. Dépiler un élément :


Dépiler revient à faire une suppression en tête.

int pop (pile* p){


int x = (**p).info;
*p= (**p).suivant;

return x;
}

...............................................................................................................................................
l’appel : int a = pop (&p1);

...............................................................................................................................................

Note : Il n’y a pas de pile pleine pour les piles dynamiques. La seule possibilité de ne pas pouvoir ajouter un élément c’est
d’avoir une mémoire pleine, cas que l’on ne prend pas en considération ici.

M. bada 7
Chapitre 4 : Les Piles et Les Files Université de Batna 2 Algorithmique et structures de données

2. Les files (Queues) :

Une file d'attente est une structure qui stocke de manière ordonnée des éléments, mais rend accessible uniquement un
seul d'entre eux, appelé la tête de la file.

Quant on ajoute un élément, celui-ci devient le dernier élément qui sera accessible.

Quant on retire un élément de la file, on retire toujours la tête, celle-ci étant le premier élément qui a été placé dans
la file.

Résumé :
Pour résumer, le premier élément ajouté dans la pile est le premier élément à en être retiré. Cette structure est
également appelée une liste FIFO (First In, First Out)

2.1. Opérations autorisées :


Les opérations autorisées avec une file sont :
Ø Initialiser une file
Ø Consulter le premier élément de la file (tête « début » de file).
Ø Vérifier si la file est vide ou non.
Ø Enfilement : ajout d’un élément à la queue de la file
Ø Défilement : retrait d’un élément (le supprimer) de la tête (le premier) de la file

2.2. Exemples d’utilisations :


En informatique une file sert essentiellement à stocker des données qui doivent être traitées selon leur ordre d’arrivée.

• L’exemple le plus connu d’une file informatique est celui de l’impression de documents reçus par une
imprimante qui imprime le premier document arrivé et termine par le dernier.
• La gestion des programmes à exécuter
• Gérer des processus en attente d'une ressource système.
• La simulation : modélisation d’une file d’attente des clients devant un guichet
• les messages en attente dans un commutateur de réseau téléphonique.

2.3. Représentation d’une file (Queue):


Comme pour les listes et les piles, Il n’existe pas de structures spécifiques prévues dans les langages de
programmation pour les files. On peut implémenter une file selon le besoin en utilisant un tableau (file statique) ou
encore des pointeurs (file dynamique).

M. bada 8
Chapitre 4 : Les Piles et Les Files Université de Batna 2 Algorithmique et structures de données
2.3.1. Représentation 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 (Début).
• Un deuxième indice entier qui pointe la dernière valeur ajoutée (Queue).

struct File {
etudiant Tab [8] ;
int Debut;
int Queue ;
};
typedef struct File File;

Conditions :
Sachant que le tableau est indicé de 0 à N-1 et pour une gestion simpliste des files :

1- Une file qui vient d’être déclarée (et non encore utilisée) : Début = 0 et Queue = -1

Début =0

Queue =-1

2- Une file a un seul élément : Début = 0 et Queue = 0 (cas générale : Début = Queue)

Début =0

3
Queue =0

3- Une file a 3 éléments : Début = 0 et Queue = 2


Début =0

3 6 -5

Queue
=2

4- Une file complètement vidée : Début = Queue +1 (ou : Début > Queue)

Début =3

3 6 -5

Queue
=2

5- Une file pleine : Queue = N (le tableau est indicé de 0 jusqu'à N-1)

Début =3
3 6 -5 19 3 11

Queue =N-1

M. bada 9
Chapitre 4 : Les Piles et Les Files Université de Batna 2 Algorithmique et structures de données

Note : il existe une autre façon de considérer les files (en circulaire).

En effet, vu qu’en défilant c’est le Début qui se rapproche de la Queue et que les cases qui se
trouvent avant le Début sont supposées devenues vides è il est possible de les réutiliser si la file
est pleine d’en haut. è Il suffirait que Queue soit remise à 0 et s’incrémente jusqu’à comblement
des cases qui se trouvent avant le Début (ex : en jaune « i=0,1 et 2) .
è file circulaire pleine : Taille de la pile = N / taille = fin – début +1

2.3.1.1. Initialisation d’une file statique :


Permet d’initialiser une file à vide lors de sa création

void Init_file (File* F) {


(*F).Debut = 0 ;
(*F).Queue = -1 ;
}

//passage par adresse


File f1;
Init_file(&f1);

2.3.1.2. Vérification si la file est vide :


Pour vérifier si une file est vide ou non et savoir alors s’il reste des valeurs à traiter ou non

int File_vide (File F){


if ( (F).Debut > (F).Queue )
{
return 1 ;
}else
{
return 0 ;
}
}

2.3.1.3. Vérification si la file est pleine :


Pour vérifier s’il est possible de rajouter ou non un nouveau élément (utilisée dans le seul cas des piles statiques)

int File_Pleine (File F){


int taille = F.Queue - F.Debut +1 ;
if ( taille == MAX) {
return 1 ;
}else
{
return 0 ;
}
}

M. bada 10
Chapitre 4 : Les Piles et Les Files Université de Batna 2 Algorithmique et structures de données
2.3.1.4. Enfiler un élément dans une file circulaire (passage par adresse) : (Queue = Queue + 1)

Il s’agit d’incrémenter (faire avancer la queue) la Queue de la file è ceci permet d’ajouter une nouvelle valeur
(envoyé en paramètre par l’appelant) à la file.

void Enfiler ( File *F , etudiant e){


if ( File_Pleine (*F) ){
printf (" Impossible, la file est pleine \n") ;
}else {
(*F).Queue = (*F). Queue + 1 ; //incrémenter la Queue
(*F).Tab [(*F).Queue % MAX] = e ; //insérer le nouvel élément dans : la Queue mod MAX
printf (" l'élément est inséré avec succès \n") ;
}
}

//passage par adresse


File f1;
Init_file(&f1);
etudiant e ;

//initialiser e......
Enfiler(&f1,e);

2.3.1.5. Défiler un élément dans une file circulaire : (Début = Début + 1)

etudiant Defiler ( File *F){


etudiant x ;
if ( File_vide (*F) )
{
printf (" Impossible, la file est vide \n") ;
}else
{
x= (*F).Tab [ (*F).Debut % MAX ] ;
(*F).Debut = (*F).Debut + 1 ;
printf (" l'élément est supprimé avec succès \n") ;
return x ;
}
}

M. bada 11
Chapitre 4 : Les Piles et Les Files Université de Batna 2 Algorithmique et structures de données
2.3.2. Représentation Dynamique d’une file:

struct Element {
int info;
Element* suivant;
};

typedef Element* file;

2.3.2.1. Initialisation d’une file:

file Init_file() {
return NULL;

.......................................................
L’appel : file f1;
f1= Init_file();
.......................................................

2.3.2.2. Tester si la file est vide :

int File_vide (file P){

if (P==NULL){
return 1;
}else{
return 0;
}

M. bada 12
Chapitre 4 : Les Piles et Les Files Université de Batna 2 Algorithmique et structures de données

2.3.2.3. Enfiler un élément (insertion à la fin) :

file enfiler (file f, int x ){

Element* position;
position= f;

//allocation d’espace mémoire pour le nouvel élément


Element* e;
e= (Element*) malloc (sizeof (Element) );
(*e).suivant = NULL;

//copier la valeur de x dans le nouvel élément


(*e).info = x;

// S’il s’agit du 1 élémenter

if (f==NULL){
f=e;
return f;

}else {
// Enfiler un autre élément

//pointer vers le dernier élément


while ((*position).suivant != NULL){

position = (*position).suivant;
}

//établir la liaison
(*position).suivant= e;

return f;
}
}
............................................................................................................
file f1;
f1= Init_file();

f1= enfiler (f1,23);


f1= enfiler (f1,13);
f1= enfiler (f1,44);
...........................................................................................................

2.3.2.4. Défiler un élément

Défiler est équivalent à dépiler et consiste à supprimer l'élément de tête si la file n'est pas vide.

int depiler (file* f){

if ( *f == NULL){
printf ("\n la file est vide \n");

}esle{
int x = (**f).info;
*f= (**f).suivant;
return x;

}
}

M. bada 13
Chapitre 4 : Les Piles et Les Files Université de Batna 2 Algorithmique et structures de données
3. Conclusion :
On a vue dans ce chapitre deux nouvelles structures de données qui sont très importante en informatique et qu’on les trouve
partout.
Le choix de l’implémentation des piles ou des files dépend du cas d’utilisation:
Une implémentation contiguë s’avère utile dans les cas où le volume d’information n’est pas important.
Dans le cas contraire, l’emploi des pointeurs permet d’économiser de l’espace mémoire.

M. bada 14

Vous aimerez peut-être aussi