Vous êtes sur la page 1sur 60

File

Queue
Ö Alexia Ben Christ Katy Karen Nicolas Patrick
Ö Ö Ö Ö Ö Ö Ö

Queue
FirstIn
FirstIn
0
Queue

K a ty
Sassia LastIn
5

ch
04:16

Za
Christ
07:37

11
-

0
ia
Alex

10
Ken

1
9 2
11:35 File
8 3
Mike Nico
las

4
15:48 -

5
6
Alexia

K
15:53

ar
P a tr

en
Karen
-

19:02
ic k
-

LastIn

© ÉTS - GPA - GPA665 2


Définition d’une file (1/3)

ƒ Selon le Dictionnaire de l’informatique de Larousse, une file se


définit comme suit :
ƒ Rangement par ordre chronologique, des évènements associés à
plusieurs processus.
ƒ Ainsi, une file correspond à une liste dont les données sont
organisées suivant le mode d’organisation par position.
ƒ Cette organisation par position se traduit par l’acronyme suivant :
FIFO (First In – First Out)
ƒ On appel aussi les files, les listes de priorité ou les files de priorité.
ƒ En anglais : file = queue.
Queue
Sassia Christ Ken Mike Alexia Karen
04:16 07:37 11:35 15:48 15:53 19:02

Schéma d’une file


(Classement selon l’heure d’arrivée)

© ÉTS - GPA - GPA665 3


Définition d’une file (2/3)

ƒ Le comportement du TDA file permet de modéliser


certaines structures du monde réel telles que :
ƒ les lignes de clients :
ƒ dans un restaurant ou dans un hôpital;
ƒ des services informatiques à même un logiciel;
ƒ des services informatiques dans un réseau;
ƒ ….
ƒ La définition même de la file indique quel doit être le
comportement de cette dernière :
ƒ l’insertion d’un enregistrement doit se faire à la fin de la liste;
ƒ la suppression d’un enregistrement doit se faire au début de la
liste;
ƒ comme la suppression, la consultation d’un enregistrement doit
se faire au début de la liste.
© ÉTS - GPA - GPA665 4
Définition d’une file (3/3)

ƒ Définition des services d’une file


ƒ Créer une file vide Create(…)
ƒ Déterminer si la file est vide IsEmpty(…)
ƒ Insérer un enregistrement dans la file Add(…)
(insertion en queue de liste)
ƒ Supprimer un enregistrement de la file Remove(…)
(suppression en tête de liste)
ƒ Consulter un enregistrement de la file QueueFront(…)
(consultation en tête de liste)

ƒ Un axiome pour les files :


QueueFront(Add(...Add(Add(Add(Queue,I1),I2),I3)...In)) = I1

© ÉTS - GPA - GPA665 5


Implémentation d’une file par une liste chaînée (1/12)

ƒ Quelle structure de liste chaînée utiliser ?


ƒ Puisqu’on désire toujours insérer à la fin et supprimer au début
de la liste, une simple liste chaînée nécessite l’usage d’un
pointeur de tête et d’un pointeur de queue.
Queue
Head
Ö Alexia Ben Christ Katy Karen Nicolas Patrick
Tail Ö Ö Ö Ö Ö Ö Ö
Ö

ƒ Une solution élégante est d’utiliser une liste circulaire, qui


nécessite seulement un pointeur de liste.

Queue
Ö Alexia Ben Christ Katy Karen Nicolas Patrick
Ö Ö Ö Ö Ö Ö Ö

© ÉTS - GPA - GPA665 6


Implémentation d’une file par une liste chaînée (2/12)

Avec ce mode d’implémentation, une TDA file est défini


comme suit :
ƒ on utilise une liste chaînée circulaire;
ƒ on utilise un seul pointeur pour la file (en pointant sur le dernier
élément, on peut accéder à toute la liste).

ƒ La fonction de création a le rôle d’initialiser


correctement le pointeur de tête à une valeur nulle
(pour ainsi assurer la cohérence de la liste dès le départ).

© ÉTS - GPA - GPA665 7


Implémentation d’une file par une liste chaînée (3/12)

1. Déclaration du type nécessaire à la file.


#define STRLENGTH 25

typedef struct _node {


char Data[STRLENGTH];
struct _node *Next;
} SNode;

2. Fonction de création de la liste (qui consiste à initialiser le pointeur de tête à


une valeur nulle).
void Create(SNode **Queue)
{
*Queue = NULL;
}

3. Fonction questionnant la file à savoir si elle est vide.


int IsEmpty(SNode *Queue)
{
return (Queue == NULL) ? 1 : 0;
}

© ÉTS - GPA - GPA665 8


Implémentation d’une file par une liste chaînée (4/12)

4. Fonction de destruction de la file.


void Destroy(SNode **Queue)
{
SNode *TempNode, *Cur;
/* Libère tous les premiers noeuds de la liste tant qu'il en reste */
if (!IsEmpty(*Queue)) {
Cur = (*Queue)->Next;
do {
TempNode = Cur;
Cur = Cur->Next;
free(TempNode);
} while (Cur != *Queue);
*Queue = NULL;
}
}

5. Fonction retournant le premier enregistrement de la file.


SNode* QueueFront(SNode *Queue)
{
if (IsEmpty(Queue)) {
return NULL;
} else {
return Queue->Next;
}

9
}
© ÉTS - GPA - GPA665
Implémentation d’une file par une liste chaînée (5/12)

6. Fonction d’insertion (exemple : ajouter l’enregistrement John)


1. Description logique. Cette fonction s’effectue en 3 opérations :
Puisqu’on connaît la position d’insertion (toujours à la fin), aucune recherche de
position n’est nécessaire.

Queue Queue
Ö Ö Nicolas Katy Ben Alexia Karen
Ö Ö Ö Ö Ö

John John

On illustre, dans le cadre d’une opération d’insertion, les deux cas limites
(insertion dans une file vide à gauche – insertion dans une file non-vide à droite)

§ allouer la mémoire nécessaire au nouvel enregistrement;


New New
Ö Ö

Queue Queue
Ö - Ö Nicolas Katy Ben Alexia Karen -
Ö Ö Ö Ö Ö Ö Ö

John John
© ÉTS - GPA - GPA665 10
Implémentation d’une file par une liste chaînée (6/12)

6. Fonction d’insertion (suite)


1. Description logique (suite).
2. copier les données dans le nouvel enregistrement;
New New
Ö Ö

Queue Queue
Ö John Ö Nicolas Katy Ben Alexia Karen John
Ö Ö Ö Ö Ö Ö Ö

3. ajuster les variables de liens.


New New
Ö Ö

Queue Queue
Ö John Ö Nicolas Katy Ben Alexia Karen John
Ö Ö Ö Ö Ö Ö Ö

© ÉTS - GPA - GPA665 11


Implémentation d’une file par une liste chaînée (7/12)

6. Fonction d’insertion (suite)


2. Définition du prototype de la fonction (définition des entrées/sorties)
int Add(SNode **Queue, char NewValue[])

3. Définition des parties logiques par des pseudo-codes :


1. allouer la mémoire nécessaire au nouvel enregistrement;
New = nouvel enregistrement

2. copier les données dans le nouvel enregistrement;


La valeur de New = NewValue

3. ajuster les variables de liens.


Si la liste est vide
Le prochain de New = New
Sinon
Le prochain de New = Le prochain du pointeur de la file
Le prochain du pointeur de la file = New
Fin du si

Le pointeur de la file = New;

© ÉTS - GPA - GPA665 12


Implémentation d’une file par une liste chaînée (8/12)

6. Fonction d’insertion (suite)


4. Écriture finale du code en langage C
int Add(SNode **Queue, char NewValue[])
{
SNode *New;

/* Allocation dynamique et copie des données */


if ((New = (SNode*) malloc(sizeof(SNode))) != NULL) {
strcpy(New->Data, NewValue);

/* Ajustement des variables de contrôle (de liens) */


if (IsEmpty(*Queue)) { /* Insertion dans une file vide */
New->Next = New;
} else { /* Insertion dans une file non vide */
New->Next = (*Queue)->Next;
(*Queue)->Next = New;
}
*Queue = New;
return 1;
} else {
return 0;
}
}

© ÉTS - GPA - GPA665 13


Implémentation d’une file par une liste chaînée (9/12)

7. Fonction de suppression
1. Description logique. Cette fonction s’effectue en 2 opérations :
Puisqu’on connaît la position de suppression (toujours au dé
début), aucune
recherche de position n’est nécessaire.

Queue Queue
Karen Ö Nicolas Katy Ben Alexia Karen Ö
Ö Ö Ö Ö Ö Ö

On illustre, dans le cadre d’une opération de suppression, les deux cas limites
(suppression dans une file ayant 1 item à gauche – suppression dans une file ayant plus d’un items à droite )

© ÉTS - GPA - GPA665 14


Implémentation d’une file par une liste chaînée (10/12)

7. Fonction de suppression (suite)


1. Description logique (suite).
1. ajuster les variables de contrôle et de liens;

Queue Queue
Karen Ö Nicolas Katy Ben Alexia Karen Ö
Ö Ö Ö Ö Ö Ö
Old Old
Ö Ö

2. libérer la mémoire associée à l’enregistrement à libérer.

Queue Queue
Karen Ö Nicolas Katy Ben Alexia Karen Ö
Ö Ö Ö Ö Ö Ö
Old Old
Ö Ö

© ÉTS - GPA - GPA665 15


Implémentation d’une file par une liste chaînée (11/12)

7. Fonction de suppression (suite)


2. Définition du prototype de la fonction (définition des entrées/sorties)
int Remove(SNode **Queue)

3. Définition des parties logiques par des pseudo-codes :


1. ajuster les variables de contrôle et de liens;
Old = Le prochain du pointeur de la file

Si Le prochain du pointeur de la file = le pointeur de la file


Le pointeur de la file = NULL
Sinon
Le prochain du pointeur de la file =
le prochain du prochain du pointeur de la file

2. libérer la mémoire associée à l’enregistrement à libérer.


Libérer Old

© ÉTS - GPA - GPA665 16


Implémentation d’une file par une liste chaînée (12/12)

7. Fonction de suppression (suite)


4. Écriture finale du code en langage C
int Remove(SNode **Queue)
{
SNode *Old;

/* S'assure qu'il reste au moins un enregistrement dans la file */


if (IsEmpty(*Queue)) {
return 0;
} else {
/* Ajustement des variables de contrôle (de liens) */
Old = (*Queue)->Next;
if ((*Queue)->Next == *Queue) { /* Supprime le dernier de la liste */
*Queue = NULL;
} else {
(*Queue)->Next = (*Queue)->Next->Next;
}

/* Libération de la mémoire */
free(Old);
return 1;
}
}

© ÉTS - GPA - GPA665 17


Implémentation d’une file par un tableau statique (1/15)

ƒ La gestion d’une file dans un tableau nécessite une approche


particulière.
ƒ L’utilisation d’indexes indiquant les positions de début et de fin de la
file dans le tableau est nécessaire.
ƒ Par contre, le fait d’incrémenter simplement ces deux indexes à chaque
suppression et insertion implique que les données seront tassées à
droite après plusieurs manipulations.
Queue
T1 LastIn FirstIn Data 0 1 2 3 4 5 6 7
2 0 Katy Zach Alexia - - - - -

Queue
T2 LastIn FirstIn Data 0 1 2 3 4 5 6 7
5 1 - Zach Alexia Nicolas Patrick Karen - -

Queue
T3 LastIn FirstIn Data 0 1 2 3 4 5 6 7
7 3 - - - Nicolas Patrick Karen Marc Maria

© ÉTS - GPA - GPA665 18


Implémentation d’une file par un tableau statique (2/15)

ƒ Une solution possible est le décalage à gauche des données.


ƒ À chaque insertion on insère à la fin de la file (ce qui n’engendre aucun
problème si le tableau n’est pas plein).
ƒ Par contre, à chaque suppression, on décale à gauche TOUS les
enregistrements (sauf le premier)!

Queue
T1 LastIn Data 0 1 2 3 4 5 6 7 8 9
5 Katy Zach Alexia Nicolas Karen Patrick - - - -

Queue
T2 LastIn Data 0 1 2 3 4 5 6 7 8 9
4 Zach Alexia Nicolas Karen Patrick Patrick - - - -

ƒ Malheureusement, le décalage rend les manipulations de la file


inefficace.
© ÉTS - GPA - GPA665 19
Implémentation d’une file par un tableau statique (3/15)

ƒ Une solution élégante est de gérer le tableau comme une liste


circulaire.
ƒ On insère à la suite de la file et on incrémente l’indice de tête.
Queue
ƒ À chaque suppression FirstIn
FirstIn
0
on incrémente

K aty
LastIn
l’indice de 5

ch
Za
queue.

11
-

0
ia
Alex

10
ƒ

1
Si l’un 9 2
File
ou l’autre 8 3
Nico
dépasse le las

4
-

5
6
dernier élément

K
physique du

ar
P a tr

en
-

tableau, on

ic k
recommence à 0. -
LastIn

© ÉTS - GPA - GPA665 20


Implémentation d’une file par un tableau statique (4/15)

ƒ Cet enroulement résout les problèmes des tableaux tassés à droite


ou du décalage à gauche.
ƒ Le seul problème avec ces tableaux est de savoir si le tableau est
vide ou s’il est plein.
Queue Queue
FirstIn FirstIn
7 8
-

-
LastIn Après LastIn
7 7
-
-

-
suppression
dans un
11

11
- - -
0

0
10

10
1

1
9 2 9 2
File File
8 3 8 3
- tableau
7

4
- FirstIn -
5
6

5
6
contenant un
asl
co

FirstIn seul élément


Ni

-
-

-
LastIn
LastIn

-
-

-
-

© ÉTS - GPA - GPA665 21


Implémentation d’une file par un tableau statique (5/15)

Queue Queue
FirstIn FirstIn
8 Jo h n 8

Jo h n
n

n
K are

K are
LastIn Après LastIn
6 7
Al

Al
k

k
insertion dans

ic

ic
ex

ex
tr

tr
ia

ia
Pa

Pa
un tableau
11

11
Zach Zach
0

0
Ben Ben
10

10
1

1
9 2 9 2
File File
8 3 8 3
Mike Mike
Katy Katy
7

7
4

4
FirstIn contenant t - 1 FirstIn
5

5
6

6
éléments

l
ro
S te p

S te p
Ka

Ka
Ca
r

r
-

l
a

a
où t est la taille LastIn
M a ri

M a ri
h an

h an
du tableau
LastIn

ƒ Dans les deux cas, l’indexe FirstIn est une position devant l’indexe
LastIn.
ƒ Une solution simple consiste à maintenir un compteur du nombre
d’enregistrements présent dans la file.
© ÉTS - GPA - GPA665 22
Implémentation d’une file par un tableau statique (6/15)

Avec ce mode d’implémentation, on définit le TDA file


comme suit :
ƒ on utilise un tableau statique;
ƒ on utilise deux indexes pour la file (un indexe indiquant le premier
enregistrement inséré et un deuxième indexe indiquant le dernier inséré).
ƒ on utilise un compteur du nombre d’enregistrements dans la file

ƒ En fait, les fonctions de création et de destruction ont un


rôle d’initialisation seulement car c’est le compilateur
qui se charge de l’allocation mémoire de toute la file.
ƒ La fonction de création a le rôle d’initialiser
correctement les deux indexes et le compteur
(pour assurer la cohérence de la liste dès le départ).

© ÉTS - GPA - GPA665 23


Implémentation d’une file par un tableau statique (7/15)

1. Déclaration du type nécessaire à la file.


#define MAXQUEUESIZE 100
#define STRLENGTH 25

typedef struct {
char Data[MAXQUEUESIZE][STRLENGTH];

int FirstIn;
int LastIn;
int Count;
} SQueue;

2. Fonction de création de la liste (qui consiste à initialiser les différentes


variables de contrôle).
void Create(SQueue *Queue)
{
Queue->LastIn = MAXQUEUESIZE - 1;
Queue->FirstIn = 0;
Queue->Count = 0;
}

© ÉTS - GPA - GPA665 24


Implémentation d’une file par un tableau statique (8/15)

3. Fonction questionnant la file à savoir si elle est vide.


int IsEmpty(SQueue *Queue)
{
return (Queue->Count == 0) ? 1 : 0;
}

4. Fonction retournant le premier enregistrement de la file.


char* QueueFront(SQueue *Queue)
{
if (IsEmpty(Queue)) {
return NULL;
} else {
return Queue->Data[Queue->FirstIn];
}
}

© ÉTS - GPA - GPA665 25


Implémentation d’une file par un tableau statique (9/15)

5. Fonction d’insertion (exemple : ajouter l’enregistrement Alexia)


1. Description logique. Cette fonction s’effectue en 4 opérations :
Puisqu’on connaît la position d’insertion (toujours à la fin), aucune recherche de
position n’est nécessaire.
§ s’assurer qu’il reste au moins un espace de libre dans le tableau;
§ ajuster les indexes;
Queue Queue
FirstIn FirstIn
1 0
FirstIn 2 0
FirstIn

K a ty
-

K a ty

LastIn LastIn
4 5

ch
-

ch

Za
Za

11
11

- -

0
ck
0

ck Patri
Patri

10
10

1
1

9 2 9 2
File File
8 3 8 3
Nico Nico
las las

4
-
7

5
6
5
6

K
K

ar
ar

en
en

-
-

LastIn
Count Count

-
-

5 5 LastIn

© ÉTS - GPA - GPA665 26


Implémentation d’une file par un tableau statique (10/15)

5. Fonction d’insertion (suite)


1. Description logique (suite).
3. copier les données dans le nouvel enregistrement;
4. ajuster la variable de comptage.

Queue Queue
FirstIn FirstIn
3 0
FirstIn 4 0
FirstIn
-

-
K a ty

K a ty
LastIn LastIn
5 5
-

-
ch

ch
Za

Za
11

11
- -
0

0
ick ick
Patr Patr
10

10
1

1
9 2 9 2
File File
8 3 8 3
Nico Nico
las las
7

7
4

4
- -
5

5
6

6
K

K
ar

ar
en

en
A le x

A le x
-

-
Count Count
ia

ia
-

-
5 LastIn 6 LastIn

© ÉTS - GPA - GPA665 27


Implémentation d’une file par un tableau statique (11/15)

5. Fonction d’insertion (suite)


2. Définition du prototype de la fonction (définition des entrées/sorties)
int Add(SQueue *Queue, char NewValue[])

3. Définition des parties logiques par des pseudo-codes :


1. s’assurer qu’il reste au moins un espace de libre dans le tableau;
Count < Taille physique du tableau

2. ajuster les indexes;


LastIn = LastIn + 1 (en considérant le tableau circulaire)

3. copier les données dans le nouvel enregistrement;


La chaîne de caractères à l’indexe LastIn = NewValue

4. ajuster la variable de comptage.


Count = Count + 1

© ÉTS - GPA - GPA665 28


Implémentation d’une file par un tableau statique (12/15)

5. Fonction d’insertion (suite)


4. Écriture finale du code en langage C
int Add(SQueue *Queue, char NewValue[])
{
/* S'assure qu'il reste dans la place dans le tableau */
if (Queue->Count < MAXQUEUESIZE) {
Queue->LastIn = (Queue->LastIn + 1) % MAXQUEUESIZE;
strcpy(Queue->Data[Queue->LastIn], NewValue);
Queue->Count++;
return 1;
} else {
return 0;
}
}

© ÉTS - GPA - GPA665 29


Implémentation d’une file par un tableau statique (13/15)

6. Fonction de suppression
1. Description logique. Cette fonction s’effectue en 3 opérations :
Puisqu’on connaît la position de suppression (toujours au dé
début), aucune recherche
de position n’est nécessaire.
1. s’assurer qu’il y a au moins un enregistrement dans le tableau;
2. ajuster les indexes;
3. ajuster la variable de comptage
Queue Queue
FirstIn FirstIn
1 8 2 et 3 9
E r ic k

E r ic k
ic k

ic k
LastIn LastIn
P atr

P atr
4 4
M

M
a

a
xi

xi
ar

ar
le

le
ia

ia
A

A
11

11
Fran rt FirstIn Fran rt
0

0
ck Robe ck Robe
10

10
1

1
9 2 9 2
File File
8 3 8 3
st
Chri Van Van
7

7
4

4
FirstIn -
5

5
6

6
K

K
ar

ar
en

en
-

-
LastIn LastIn
Count Count
-

-
-

-
9 8

© ÉTS - GPA - GPA665 30


Implémentation d’une file par un tableau statique (14/15)

6. Fonction d’insertion (suite)


2. Définition du prototype de la fonction (définition des entrées/sorties)
int Remove(SQueue *Queue)

3. Définition des parties logiques par des pseudo-codes :


1. s’assurer qu’il y a au moins un enregistrement dans le tableau;
Si NON(IsEmpty)

2. ajuster les indexes;


FirstIn = FirstIn + 1 (en considérant le tableau circulaire)

3. ajuster la variable de comptage.


Count = Count - 1

© ÉTS - GPA - GPA665 31


Implémentation d’une file par un tableau statique (15/15)

6. Fonction d’insertion (suite)


4. Écriture finale du code en langage C
int Remove(SQueue *Queue)
{
/* S'assure qu'il reste au moins un enregistrement dans la file */
if (IsEmpty(Queue)) {
return 0;
} else {
Queue->FirstIn = (Queue->FirstIn + 1) % MAXQUEUESIZE;
Queue->Count--;
return 1;
}
}

© ÉTS - GPA - GPA665 32


Pile
Stack Stack Karen
Ö Nicolas Katy Ben Alexia Karen 19:02
Ö Ö Ö Ö Ö Alexia
15:53
Mike
15:48
Ken
11:35
Christ
07:37
Sassia
04:16

© ÉTS - GPA - GPA665 33


Définition d’une pile (1/3)

ƒ Selon le Dictionnaire de l’informatique de Larousse, une pile se


définit comme suit :
ƒ File gérée selon la méthode du dernier entré, premier sorti.
ƒ Ainsi, une pile correspond à une liste dont les données sont
organisées suivant le mode d’organisation par position.
ƒ Cette organisation par position se traduit par l’acronyme suivant :
LIFO (Last In – First Out).
ƒ En anglais : pile = stack. Stack Karen
19:02
Alexia
15:53
Mike
15:48
Ken
11:35
Christ
07:37
Schéma d’une pile Sassia
(Classement selon l’heure d’arrivée) 04:16

© ÉTS - GPA - GPA665 34


Définition d’une pile (2/3)

ƒ Le comportement du TDA pile permet de modéliser


certaines structures du monde réel telles que :
ƒ des empilements de stock;
ƒ la gestion de certains services informatiques (comme les appels de
fonctions);
ƒ ….

ƒ La définition même de la pile indique quel doit être le


comportement de cette dernière :
ƒ l’insertion d’un enregistrement doit se faire au début de la liste;
ƒ la suppression d’un enregistrement doit se faire au début de la
liste;
ƒ comme l’insertion et la suppression, la consultation d’un
enregistrement se fait au début de la liste.
© ÉTS - GPA - GPA665 35
Définition d’une pile (3/3)

ƒ Définition des services d’une pile


ƒ Créer une pile vide Create(…)
ƒ Déterminer si la pile est vide IsEmpty(…)
ƒ Insérer un enregistrement dans la pile Push(…)
(insertion en queue de liste)
ƒ Supprimer un enregistrement de la pile Pop(…)
(suppression en tête de liste)
ƒ Consulter un enregistrement de la pile StackTop(…)
(consultation en tête de liste)

ƒ Un axiome pour les piles :


Pop(Push(Stack,I)) = Stack

© ÉTS - GPA - GPA665 36


Implémentation d’une pile par une liste chaînée (1/11)

ƒ Encore une fois, on peut se demander quelle est la


structure la plus adéquate pour une telle
implémentation.
ƒ Puisqu’on désire toujours insérer et supprimer au début de la
liste, une liste chaînée standard convient parfaitement.
Stack
Ö Nicolas Katy Ben Alexia Karen
Ö Ö Ö Ö Ö

ƒ La fonction de création a le rôle d’initialiser


correctement le pointeur de tête à une valeur nulle
(pour ainsi assurer la cohérence de la liste dès le départ).
ƒ La fonction de destruction quant à elle, doit s’assurer de
tout libérer la mémoire préalablement allouée pour la
pile.
© ÉTS - GPA - GPA665 37
Implémentation d’une pile par une liste chaînée (2/11)

1. Déclaration du type nécessaire à la file.


#define STRLENGTH 25

typedef struct _node {


char Data[STRLENGTH];
struct _node *Next;
} SNode;

typedef SNode* SStack;

2. Fonction questionnant la file à savoir si elle est vide.


int IsEmpty(SStack pStack)
{
return (pStack == NULL) ? 1 : 0;
}

3. Fonction de création de la liste (qui consiste à initialiser le pointeur de tête à


une valeur nulle).
void Create(SStack *pStack)
{
*pStack = NULL;
}

© ÉTS - GPA - GPA665 38


Implémentation d’une pile par une liste chaînée (3/11)

4. Fonction de destruction de la file.


void Destroy(SStack *pStack)
{
SNode *TempNode;

/* Libère tous les premiers noeuds de la liste tant qu'il en reste */


while (*pStack != NULL) {
TempNode = *pStack;
*pStack = (*pStack)->Next;
free(TempNode);
}
*pStack = NULL;
}

5. Fonction retournant le premier enregistrement de la file.


SNode* StackTop(SStack Stack)
{
return Stack;
}

© ÉTS - GPA - GPA665 39


Implémentation d’une pile par une liste chaînée (4/11)

6. Fonction d’insertion (exemple : ajouter l’enregistrement John)


1. Description logique. Cette fonction s’effectue en 3 opérations :
Puisqu’on connaît la position d’insertion (toujours à la fin), aucune recherche de
position n’est nécessaire.
Stack
Ö Nicolas Katy Ben Alexia Karen
Ö Ö Ö Ö Ö

John

1. allouer la mémoire nécessaire au nouvel enregistrement;


Stack
Ö Nicolas Katy Ben Alexia Karen
Ö Ö Ö Ö Ö
New
-
Ö John
Ö

© ÉTS - GPA - GPA665 40


Implémentation d’une pile par une liste chaînée (5/11)

6. Fonction d’insertion (suite)


1. Description logique (suite).
2. copier les données dans le nouvel enregistrement;

Stack
Ö Nicolas Katy Ben Alexia Karen
Ö Ö Ö Ö Ö
New
John
Ö
Ö

3. ajuster les variables de liens.


Stack
Ö Nicolas Katy Ben Alexia Karen
Ö Ö Ö Ö Ö
New
John
Ö
Ö

© ÉTS - GPA - GPA665 41


Implémentation d’une pile par une liste chaînée (6/11)

6. Fonction d’insertion (suite)


2. Définition du prototype de la fonction (définition des entrées/sorties)
int Push(SStack *pStack, char NewValue[])

3. Définition des parties logiques par des pseudo-codes :


1. allouer la mémoire nécessaire au nouvel enregistrement;
New = nouvel enregistrement

2. copier les données dans le nouvel enregistrement;


La valeur de New = NewValue

3. ajuster les variables de liens.


Le prochain de New = La pile
La pile = New

© ÉTS - GPA - GPA665 42


Implémentation d’une pile par une liste chaînée (7/11)

6. Fonction d’insertion (suite)


4. Écriture finale du code en langage C
int Push(SStack *pStack, char NewValue[])
{
SNode *New;

/* Allocation dynamique et copie des données */


if ((New = (SNode*) malloc(sizeof(SNode))) != NULL) {
strcpy(New->Data, NewValue);

New->Next = *pStack;
*pStack = New;
return 1;
} else {
return 0;
}
}

© ÉTS - GPA - GPA665 43


Implémentation d’une pile par une liste chaînée (8/11)

7. Fonction de suppression
1. Description logique. Cette fonction s’effectue en 2 opérations :
Puisqu’on connaît la position de suppression (toujours au dé
début), aucune
recherche de position n’est nécessaire.

Stack
Ö Nicolas Katy Ben Alexia Karen
Ö Ö Ö Ö Ö

© ÉTS - GPA - GPA665 44


Implémentation d’une pile par une liste chaînée (9/11)

7. Fonction de suppression (suite)


1. Description logique (suite).
1. ajuster les variables de contrôle et de liens;
Stack
Ö Nicolas Katy Ben Alexia Karen
Ö Ö Ö Ö Ö
Old
Ö

2. libérer la mémoire associée à l’enregistrement à libérer.

Stack
Ö Nicolas Katy Ben Alexia Karen
Ö Ö Ö Ö Ö
Old
Ö

© ÉTS - GPA - GPA665 45


Implémentation d’une pile par une liste chaînée (10/11)

7. Fonction de suppression (suite)


2. Définition du prototype de la fonction (définition des entrées/sorties)
int Pop(SStack *pStack)

3. Définition des parties logiques par des pseudo-codes :


1. ajuster les variables de contrôle et de liens;
Old = Le premier enregistrement de la pile
La pile = le deuxième de la pile

2. libérer la mémoire associée à l’enregistrement à libérer.


Libérer Old

© ÉTS - GPA - GPA665 46


Implémentation d’une pile par une liste chaînée (11/11)

7. Fonction de suppression (suite)


4. Écriture finale du code en langage C
int Pop(SStack *pStack)
{
SNode *Old;

/* S'assure qu'il reste au moins un enregistrement dans la pile */


if (IsEmpty(*pStack)) {
return 0;
} else {
Old = *pStack;
*pStack = (*pStack)->Next;

free(Old);
return 1;
}
}

© ÉTS - GPA - GPA665 47


Implémentation d’une pile dans un tableau statique (1/7)

ƒ L’implémentation d’une pile dans un tableau est aussi très simple


(pour la même raison que pour la méthode d’implémentation sous forme de liste
chaînée : les insertions et les suppressions se font toujours à la même position).

Stack
Top Data 0 1 2 3 4 5 6 7
5 Katy Zach Alexia Nicolas Karen Patrick - -

ƒ En fait, les fonctions de création et de destruction ont un rôle


d’initialisation seulement car c’est le compilateur qui se charge de
l’allocation mémoire de toute la pile.
ƒ La fonction de création a le rôle d’initialiser correctement l’indexe
du dessus de la pile (pour assurer la cohérence de la liste dès le départ).

© ÉTS - GPA - GPA665 48


Implémentation d’une pile dans un tableau statique (2/7)

1. Déclaration du type nécessaire à la file.


#define MAXSTACKSIZE 100
#define STRLENGTH 25

typedef struct {
char Data[MAXSTACKSIZE][STRLENGTH];
int Top;
} SStack;

2. Fonction questionnant la file à savoir si elle est vide.


int IsEmpty(SStack *Stack)
{
return (Stack->Top < 0) ? 1 : 0;
}

© ÉTS - GPA - GPA665 49


Implémentation d’une pile dans un tableau statique (3/7)

3. Fonction de création de la liste (qui consiste à initialiser l’indexe du dessus


de la pile à -1).
void Create(SStack *Stack)
{
Stack->Top = -1;
}

4. Fonction retournant le premier enregistrement de la file.


char* StackTop(SStack *Stack)
{
return Stack->Data[Stack->Top];
}

© ÉTS - GPA - GPA665 50


Implémentation d’une pile dans un tableau statique (4/7)

5. Fonction d’insertion (exemple : ajouter l’enregistrement John)


1. Description logique. Cette fonction s’effectue en 3 opérations :
Puisqu’on connaît la position d’insertion (toujours à la fin), aucune recherche de
position n’est nécessaire.
1. s’assurer qu’il reste au moins une place de disponible dans la pile;
Stack
Top Data 0 1 2 3 4 5 6 7
5 Katy Zach Alexia Nicolas Karen Patrick - -

2. ajuster les variables de liens;


Stack
Top Data 0 1 2 3 4 5 6 7
6 Katy Zach Alexia Nicolas Karen Patrick - -

3. copier les données dans le nouvel enregistrement.


Stack
Top Data 0 1 2 3 4 5 6 7
6 Katy Zach Alexia Nicolas Karen Patrick John -

© ÉTS - GPA - GPA665 51


Implémentation d’une pile dans un tableau statique (5/7)

5. Fonction d’insertion (suite)


2. Définition du prototype de la fonction (définition des entrées/sorties)
int Push(SStack *Stack, char NewValue[])

3. Définition des parties logiques par des pseudo-codes :


1. s’assurer qu’il reste au moins une place de disponible dans la pile;
Si Top < MAX_STACK_SIZE - 1

2. ajuster les variables de liens;


Top = Top + 1

3. copier les données dans le nouvel enregistrement.


La donnée à l’indexe Top = NewValue

© ÉTS - GPA - GPA665 52


Implémentation d’une pile dans un tableau statique (6/7)

5. Fonction d’insertion (suite)


4. Écriture finale du code en langage C
int Push(SStack *Stack, char NewValue[])
{
/* S'assurer qu'il reste au moins un item de libre dans le tableau */
if (Stack->Top < MAXSTACKSIZE - 1) {
Stack->Top++;
strcpy(Stack->Data[Stack->Top], NewValue);
return 1;
} else {
return 0;
}
}

© ÉTS - GPA - GPA665 53


Implémentation d’une pile dans un tableau statique (7/7)

6. Fonction de suppression
Description logique. Cette fonction est très simple. En fait, il suffit de
décrémenter l’indexe Top si la pile n’est pas vide.

int Pop(SStack *Stack)


{
/* S'assure qu'il reste au moins un enregistrement dans la pile */
if (IsEmpty(Stack)) {
return 0;
} else {
Stack->Top--;
return 1;
}
}

© ÉTS - GPA - GPA665 54


Un exemple : Le parenthèsage! (1/2)

ƒ Une application potentielle de la pile est la validation du


niveau correct de parenthèses dans une expression.
ƒ La règle de validation est simple : en parcourant une chaîne de
caractères de gauche à droite, on doit pouvoir associer, pour
chaque fermeture de parenthèse « ) », une ouverture de
parenthèse « ( » déjà rencontrée. De plus, on doit toujours
respecter le niveau d’indentation.
ƒ Un exemple correct : y = (x+1)^2 / ((x+2)*(x-2))
ƒ Deux exemples incorrects :
ƒ z = (x+2) + y-2) - une fermeture sans ouverture
ƒ z = (x+2 / (y-2) - à la fin, il manque une fermeture

© ÉTS - GPA - GPA665 55


Un exemple : Le parenthèsage! (2/2)

ƒ Voici un pseudo-code qui permet de solutionner ce problème avec


une pile :
void Valid(S) {
continue = True;
while ((ch = getchar()) != EOL && continue){
/* ignorer tout caractère ≠ de '(' et de ')' */
if (ch == '(' || ch == ')')
if (ch == '(')
Push(S, '(');
else
if (!IsEmpty(S))
Pop(S);
else
continue = False; /*parenthèse fermée, mais plus de parenthèses ouvrantes*/
} /* while */
/* On vérifie si la le dernier caractère est bien le EOL et que la pile est vide */
if (ch == EOL && IsEmpty(S))
printf("les parenthèses sont équilibrées");
else
printf("les parenthèses ne sont pas équilibrées");
}

ƒ Évidemment, cette approche n’est pas vraiment performante. Elle


n’est ici qu’à titre d’exemple pédagogique.
© ÉTS - GPA - GPA665 56
Un exemple : Un palindrome! (1/3)

ƒ Un palindrome est une chaîne de caractères qui se lit de la même


façon de gauche à droite ainsi que de droite à gauche. Par exemple:
ƒ L'arome moral
ƒ Name now one man
ƒ Karine égarée rage en Irak
ƒ Esope reste ici et se repose
ƒ Engage le jeu, que je le gagne
ƒ Satan, oscillate my metallic sonatas
ƒ Pour ceux que ça intéresse… allez voir l’incroyable palindrome de Georges
Perec. C’est le palindrome francophone le plus long jamais écrit avec ses 1247
mots! - http://home.urbanet.ch/urba7038/motscroises/lexique/palindrome.htm

ƒ Comment, à l’aide des files et des piles, vérifier si une chaîne de


caractères est un palindrome?

© ÉTS - GPA - GPA665 57


Un exemple : Un palindrome! (2/3)

ƒ L’idée est simple : on lit la chaîne de caractères et on ajoute à la fois


dans une file et dans une pile.
ƒ Après la lecture de la chaîne de caractères, on vide chacune des
structures de données et on compare enregistrement par
enregistrement.
ƒ Si chacun des couples d’enregistrements est identique, alors la chaîne
de caractères est un palindrome.
Queue
FirstIn
FirstIn
0
-

LastIn
4
-

a
11

- Stack
0

d
10

9 2 Top Data 0 1 2 3 4 5 6 7
File R a d a r - - -
8 3 4
a
7

-
5
6
-

LastIn
Count
-

© ÉTS - GPA - GPA665 58


Un exemple : Un palindrome! (3/3)

ƒ Voici un pseudo-code qui permet de solutionner ce problème :


int Pal(W)
{ int flag; /*retourne une valeur bool*/
Create(Q) /*crée une file */
Create(S) /*crée une pile */

/*insérer chaque caractère dans la file et dans la pile*/


while ((ch = getchar()) != EOL) {
Add(Q, ch);
Push(S, ch);
}
/* comparer la file à la pile */
flag = True;
while (!IsEmpty(S) && flag) {
if (QueueFront(Q) == StackTop(S)) {
Remove(Q);
Pop(S);
} else {
flag = False;
}
}
} /* Fin de Pal() */

ƒ Encore une fois, cette approche n’est pas vraiment performante.


Elle n’est ici qu’à titre d’exemple pédagogique.
© ÉTS - GPA - GPA665 59
Quelques exercices suggérés

ƒ Supposer qu’on ait une pile S et une pile auxiliaire vide


T. Montrer comment on peut réaliser les tâches
suivantes en se servant uniquement des opérateurs de la
TDA pile.
ƒ Imprimer le contenu de S dans l’ordre inverse
ƒ Compter le nombre d’élément de S, en laissant la pile inchangée
ƒ Supprimer chaque occurrence d’un item spécifié de S, en
préservant l’ordre des éléments restants.

ƒ Faite l’implémentation de différentes allocations


mémoire, structures et organisations de files ainsi que
de piles.

© ÉTS - GPA - GPA665 60

Vous aimerez peut-être aussi