SlideShare une entreprise Scribd logo
1
Algorithmique
&
structures des données II
1ère Business Computing (BC)
Responsable : Dr. Fadoua Bouafif
Dr.Fadoua Bouafif
1
Chapitre 4
Les listes chainées
Dr.Fadoua Bouafif
Objectifs du chapitre
Dr.Fadoua Bouafif
A la fin du chapitre, les étudiants seront en mesure de:
- Définir une liste chainée en algorithmique et en langage C
- Déterminer la nécessité de la liste chainée pour la résolution des
problèmes
- Nommer les opérations de manipulation de la liste chainée
- Distinguer les différents types de listes chainées
Plan du chapitre
1. Introduction
2. Les listes chainées simples
3. Les listes circulaires
4. Les listes doublement chainées
5. Les piles et les files
6. Conclusion
Dr.Fadoua Bouafif
Introduction
3
Pour stocker un ensemble de données de même type d’une façon linéaire, les tableaux
sont utilisés. Plusieurs inconvénients se présentent pour cette structure :
1)La capacité de stockage d’un tableau est fixe  problèmes quand le nombre de
données à stocker est dynamique;
2) Les cases d’un tableau sont contigües  manque d’efficacité au niveau de la
réservation de l’espace mémoire nécessaire;
3) L’ajout et la suppression d’un élément dans un tableau nécessitent des opérations de
décalage de cases souvent coûteuses.
Prévoir une structure de données qui évite ce type
d’inconvénients  listes chaînées
Dr.Fadoua Bouafif
Introduction
ASD II
4
- La liste chainée peut contenir des éléments de types simples ou complexes
- Il existe différent types de listes chainées :
- Simple
- Double
- Circulaire
- D’autres structures sont définies en se basant sur les listes comme les piles et les files.
Dr.Fadoua Bouafif
1
Dr.Fadoua Bouafif
Les Listes Chainées Simples
1. Définition
2. Déclaration
3. Création
4. Manipulation
Définition
Une liste est une suite d’éléments, appelés cellules ou nœuds contenant chacune une zone de données et
une zone de chaînage (adresse) de l’élément suivant dans la liste.
 Tout élément de la liste (sauf le premier et le dernier) possède un successeur et un prédécesseur.
5
Chainage
Lien vers le
nœud suivant
Données Chainage
Lien vers le
nœud suivant
Données Données Chainage
Lien vers le
nœud suivant
Tête: pointe sur le premier nœ ud
Queue: pointe sur le NULL
NIL
 Le premier élément de la liste est nommé tête. C’est un pointeur qui contient l’adresse du premier nœud
de la liste.
 Le dernier élément de la liste est nommée queue. Il pointe sur NIL(NULL). Dr.Fadoua Bouafif
Définition (suite)
ASD II
6
▶ L’utilisation des pointeurs facilite la manipulation des listes.
▶ Les éléments de la liste ne sont pas contigus en mémoire : chaque nœud est référencé par une adresse
représentée par un pointeur
Exemple: une liste d’entiers
▶ Il suffit de connaître la tête pour y pouvoir accéder aux différents autres éléments
▶ Le parcours est unidirectionnel et s’effectue de gauche à droite.
▶ Si la tête pointe sur le NULL, alors la liste est vide.
Dr.Fadoua Bouafif
Déclaration
ASD II
7
En C
En Algorithme
Typedef Struct
{
type_de_données valeur;
Struct Nœud * suivant;
} Nœud;
Type Nœud=enregistrement
valeur: type_de_données
suivant : ↑ nœud
Fin_Noeud
Syntaxe
Déclaration d’un
nœud
Typedef Nœud * liste;
Type liste: ↑ Nœud
Syntaxe
Déclaration
d’une liste
Typedef Struct
{
int val;
struct Nœud * suiv;
} Nœud;
Typedef Noeud *liste;
intmain()
{
liste tete; //Nœud *tete;
………… return 0;
}
Algorithme test
Type Nœud=enregistrement
val: entier
suiv: ↑ Nœud
Fin_Noeud
Typeliste : ↑ Nœud
var : tete: liste
début
……….
Fin
Exemple
val suiv
Nœud
Création d’une cellule
La création se fait à l’aide des fonctions d’allocation dynamique.
11
En C
En algorithme
Allouer un espace mémoire pour
un nouveau nœud
#include « stdlib.h »
malloc ()
Allouer ()
Nom
fonction
nouveau est un pointeur sur le
nouveau nœud à insérer
Nœud *nouveau;
nouveau: ↑ Nœud
Déclaration
Allouer un espace mémoire
nouveau=(Noued *) malloc(sizeof(Noued);
Allouer(nouveau)
Affecter une donnée au champ
val
(*nouveau).val = valeur;
(*nouveau).valvaleur
Affecter NIL (NULL) au champ
suiv
(*nouveau).suiv = NULL;
(*nouveau).suivNIL
Dr. Fadoua.BOUAFIF
Libération d’une cellule
La libération se fait à l’aide des fonctions d’allocation dynamique
12
En C
En algorithme
libérer le noeud allouer
free ()
libérer ()
Nom fonction
libérer le noeud nouveau
free (nouveau);
libérer (nouveau)
Déclaration
Il ne faut pas oublier d’inclure la bibliothèque <stdlib.h> en C
Dr. Fadoua.BOUAFIF
Manipulation de la liste simplement chainée
▶ Les opérations de base sur les listes sont:
▶ Initialisation d’une liste à vide.
▶ Tester si la liste est vide ou non.
▶ Premier élément de la liste.
▶ Dernier élément de la liste.
▶ Insertion d’un nouveau élément (nœud) dans la liste (début, milieu, fin).
▶ Suppression d’un élément (nœud) de la liste (début, milieu, fin).
ASD II
10
Dr.Fadoua Bouafif
Manipulation de la liste simplement chainée (suite)
▶ D’autres opérations peuvent être appliquées sur les listes:
▶ Affichage des éléments d’une liste
▶ Inversion d’une liste
▶ Taille d’une liste
▶ Concaténation de deux listes
▶ Destruction d’une liste
▶ …
ASD II
11
Dr.Fadoua Bouafif
Activité1
ASD II
25
Ecrire un sous programme "Affiche()" qui permet
d’afficher le contenu d’une liste simplement chainée
d’entiers.
Dr.Fadoua Bouafif
Solution de l’activité 1
ASD II
27
}
Dr.Fadoua Bouafif
En C
En algorithmique
Procédure Affiche (tete: liste)
var: courant : liste
Début
courant  tete
si(courant== NIL)
alors écrire (‘’la liste est vide’’)
sinon écrire (‘’Contenu de la liste:’)
tant que (courant != NIL) faire
écrire ((*courant).val, " → " )
courant  (*courant).suiv
fin tant que
fin si
Fin
void affiche (liste tete)
{
liste courant = tete;
if (courant == NULL)
printf ("nLa liste est viden");
else
{ printf ("nContenu de la liste: ");
// Parcourir toute la liste
while (courant != NULL)
{
printf (" %d n", (*courant).val);
courant = (*courant).suiv;
}
}
}
Insertion d’un nouveau nœud
Etape 1: Créer le nouveau nœud
▶ Pour insérer un nouveau élément dans une liste, il faut tout d’abord créer un nouveau nœud
ASD II
12
suiv
val
nouveau
1. Déc lara tion
2. Allocation
3. Initialisation des champs (valeur et suivant)
nouveau: ↑ nœud
Allouer(nouveau) (*nouveau).val valeur
(*nouveau).suiv  NIL
Insertion d’un nouveau nœud
▶ Trois cas sont possibles pour insérer un nœud dans une liste simplement chainée
ASD II
13
2ffx04
259 2ffx08
321
Tête
98 NULL
2ffx00 2ffx04 2ffx08
2ffx00
Insertion au début Insertion au milieu Insertion à la fin
Dr.Fadoua Bouafif
Insertion d’un nouveau nœud
▶ Trois cas sont possibles pour insérer un nœud dans une liste simplement chainée
ASD II
14
259 Y Z
321
Tête
98 NULL
X Y Z
X
Insertion au début Insertion au milieu Insertion à la fin
Remarque:les lettres en majuscule représentent les adressesdes nœuds
Insertion début
Etape 2: Insérer le nouveau nœud
▶ Il faut distinguer deux cas: (1) liste vide et (2) liste non-vide.
ASD II
15
Tête NULL
NULL
Nouveau
valeur
X
Tête X
NULL
Nouveau
valeur
X
tete = nouveau;
Cas 1: Liste vide: Avant insertion Cas 1: Liste vide: Après insertion
Dr.Fadoua Bouafif
Insertion début
▶ Etape 2: Insérer le nouveau nœud
▶ Il faut distinguer deux cas: (1) liste vide et (2) liste non-vide.
16
Cas 2: Liste non-vide: Avant insertion
NIL
info
Nouveau
W
Cas 2: Liste non-vide: Après insertion
10 Y 7 Z 18 NIL
X Y Z
Tête
X
info
Nouveau
W
10 Y 7 Z 18 NIL
X Y Z
Tête
(*nouveau).suiv = tete;
tete = nouveau;
Tête
Dr.Fadoua Bouafif
Activité2
Ecrire un sous-programme « insertionTête() »qui permet
d’ajouter un entier donné au début d’une liste
Dr.Fadoua Bouafif
Insertion début
En C
En algorithme
void inserer_debut (liste *tete, int info)
{// declaration et allocation
Nœud *nouveau;
nouveau = (Noeud *) malloc (sizeof(Noeud));
if(nouveau) {
(*nouveau).val = info; // affectation
(*nouveau).suiv = NULL;
if (*tete == NULL) // la liste est vide
*tete = nouveau;
else // la liste n’est pas vide
{
(*nouveau).suiv =*tete;
*tete = nouveau;
}
}
}
Procedure inserer_debut (var tete: liste, info: entier)
Var: nouveau: ↑ Nœud
Debut
Alouer (nouveau)
(*nouveau).valinfo
(*nouveau).suivNIL
Si (tete==NIL)
alors tete nouveau
sinon
(*nouveau).suiv tete
tete  nouveau
fin si
Fin
Insertion fin
ASD II
18
L’insertion à la fin correspond à une insertion après le dernier nœud.
Nous distinguons deux cas:
• Cas 1: Liste vide
Quand une liste vide, l’insertion au début et celle à la fin sont équivalentes puisque le
nouveau nœud sera l’unique nœud de la liste.
• Cas 2: Liste non-vide
Il faut parcourir toute la liste pour accéder au dernier nœud après lequel le nouveau nœud
sera inséré.
Pour parcourir une liste, nous avons besoin d’un pointeur « courant » qui va parcourir la
liste jusqu’à ce qu’il pointe sur le dernier nœud dont le champ « suiv » est égal à NIL
Insertion fin
ASD II
19
NIL
info
Nouveau
W
10 Y 7 Z NIL
18
X Y Z
T
ête X
courant courant
Etape 2: Lier le nouveau nœud au dernier
nœud en utilisant « courant ».
10 Y 7 Z 18
X Y Z
T
ête X courant
Cas 2: Liste non-vide
Il faut parcourir toute la liste pour accéder au dernier nœud après lequel le nouveau nœud
(*courant).suiv = nouveau;
sera inséré.
Etape 1: Parcourir la liste nœud par
nœud par le pointeur « courant ».
courant  (*courant).suiv;
NIL
Activité 3
Ecrire un sous-programme « insertionFin() »qui permet
d’ajouter un entier donné à la fin d’une liste
Dr.Fadoua Bouafif
ASD II
ertion fin 20
Ins
En C
En algorithme
void inserer_fin (liste * tete, int info)
{
Noeud * nouveau; // nouveau nœud à insérer
Noeud * courant; // nœud courant
nouveau = (Noeud *) malloc (sizeof (Noeud));
(*nouveau).val = info;
(*nouveau).suiv = NULL;
if (*tete == NULL) // Si la liste est vide, nous créons un premier nœud
*tete = nouveau;
else // Si la liste n’est pas vide
{ // Parcourir la liste jusqu'au dernier nœud
courant = *tete; // Initialiser le courant à la tête de la liste
while ((*courant).suiv != NULL)
{ courant = (*courant).suiv; }
// Lier le nouveau noeud à la fin de la liste
(*courant).suiv = nouveau;
}
}
Procedure inserer_fin (var tete: liste, info: entier)
Var: nouveau, courant: ↑ Nœud
Debut
Alouer (nouveau)
(*nouveau).valinfo
(*nouveau).suiv  NIL
Si(tete==NIL)
alors tete nouveau
sinon
courant tete
Tant que ((*courant).suiv != NIL) faire
courant  (*courant).suiv
Fin tant que
(*courant).suiv  nouveau
fin si
Fin
Dr.Fadoua Bouafif
Insertion à une position donnée
ASD II
21
Principe
Soit pos la position donnée :
1) Si (pos == 1), alors c’est le cas de l’insertion au début de la liste
2) Si (pos > 1), alors deux pointeurs seront nécessairement définit:
- Pointeur courant, positionné sur le nœud à la position pos, et
- Pointeur precedent, positionné sur le nœud à la position (pos-1).
Afin de réaliser l’insertion du nœud désiré, il faut:
 lier le nœud à la position (pos-1) (pointé par precedent) au nouveau nœud;
 et après lier le nouveau nœud au nœud à la position (pos) (pointé par courant)
Dr.Fadoua Bouafif
Insertion à une position donnée
ASD II
22
55 Y
X
Tête X
20 Z
Y
T
18
Z
31 NIL
T
courant
precedent
72
Nouveau
W
(*precedent).suiv  nouveau
Exemple: Insérer le nœud 72 à la 3ème position (pos == 3).
courant
precedent
Courant  (*courant).suiv
precedent  courant
(*nouveau).suiv  courant
Courant (*tete).suiv
precedent  tete
NULL
20
Z
courant
18 T
Y
precedent
72
W
W
Nouveau
Z
1
2
3
Dr.Fadoua Bouafif
Insertion à une position donnée
en Algorithmique
ASD II
23
Procedure inserer_debut (var tete: liste, info: entier)
Procedure inserer_position (var tete: liste, info: entier, pos: entier)
var: i: entier
nouveau, precedent, courant: ↑ Noeud
Début
Allouer (nouveau)
(*nouveau).valinfo // Allocation du noeud à insérer
(*nouveau).suiv  NIL
Si (pos == 1)
alors inserer_debut (tete, info)
sinon si (pos >1)
alors
courant (*tete).suiv
precedent  tete
i  1
tant que ((courant != NIL) ET (i != (pos-1))) faire
precedent  courant
courant  (*courant).suiv
i++
fin tant que
si ((pos-1) == i) // Réaliser l'insertion
alors (*precedent).suiv  nouveau
(*nouveau).suiv  courant
sinon écrire (‘’position erronée’’)
fin si
sinon écrire (‘’position erronée’’)
fin si
fin si
Fin
Insertion à une position donnée
En C
ASD II
24
void inserer_debut (liste *tete, int info);
void inserer_position (liste *tete, int info, int pos)
{ int i;
Noeud *nouveau, *precedent, *courant;
// Allocation du noeud à insérer
nouveau = (struct noeud*) malloc (sizeof (struct noeud));
If (nouveau){
(*nouveau).val = info;
(*nouveau).suiv = NULL;
if (pos == 1)
inserer_debut (tete, info);
else
{ if (pos >1)
{ courant = (*(*tete)).suiv;
precedent= *tete;
i = 1;
While ((courant) && (i != (pos-1)))
{ precedent = courant;
courant = (*courant).suiv;
i++;
}
if ((pos-1) == i) // Réaliser l'insertion
{
(*precedent).suiv = nouveau;
(*nouveau).suiv = courant;
}
else
printf (‘’position erronée’’);
}
else printf (‘’position erronée’’);
}
}}
Activité 4
Ecrire un sous-programme « insertion()»qui permet d’ajouter
un entier donné à une liste triée
Dr.Fadoua Bouafif
Insertion une donnée à une liste triée
en Algorithmique
ASD II
23
Procedure inserer_debut (var tete: liste, info: entier)
Procedure inserer_contenue (var tete: liste, x: entier)
var: i: entier
nouveau, precedent, courant: ↑ Noeud
Début
Allouer (nouveau)
(*nouveau).valx // Allocation du noeud à insérer
(*nouveau).suiv  NIL
Si (x >= (*tete).valeur
alors inserer_debut (tete,x)
sinon
courant (*tete).suiv
precedent  tete
tant que ((courant != NIL) ET (x<*courant.val)) faire
precedent  courant
courant  (*courant).suiv
fin tant que
si (x>=*courant.val) // Réaliser l'insertion
alors (*precedent).suiv  nouveau
(*nouveau).suiv  courant
fin si
fin si
Fin
Insertion une donnée à une liste triée
En C
ASD II
24
void inserer_debut (liste *tete, int info);
void inserer_listeTriee (liste *tete, int x)
{ int i;
Noeud *nouveau, *precedent, *courant;
// Allocation du noeud à insérer
nouveau = (struct noeud*) malloc (sizeof (struct noeud));
If (nouveau){
(*nouveau).val = x;
(*nouveau).suiv = NULL;
if (x >= (*tete).val
inserer_debut (tete, x);
else
{ courant = (*(*tete)).suiv; precedent=
*tete;
While ((courant) && (x<*courant.val))
{ precedent = courant;
courant = (*courant).suiv;
}
if (x>=*courant.val) // Réaliser l'insertion
{
(*precedent).suiv = nouveau;
(*nouveau).suiv = courant;
}
}
}
Suppression d’une cellule
ASD II
28
La suppression d’un nœud peut se faire sur la base du contenu du nœud ou de sa
position. Dans les deux cas, nous avons besoin des deux pointeurs:
1) courant: positionné sur le nœud à supprimer, et
2) precedent: positionné sur le nœud qui précède le nœud à supprimer.
Le principe de la suppression est de lier le nœud précédent au nœud suivant et par
la suite libérer (supprimer) le nœud courant.
Dr.Fadoua Bouafif
Suppression selon le contenu du nœud
ASD II
29
Y
55
X
Tête X
Z
20
Y
W
18
Z
NULL
31
W
courant
Tête Y
Si le nœud à supprimer est le premier nœud de la liste, alors la tête avance vers le
deuxième nœud et nous libérons le premier nœud.
Exemple: Supprimer 55.
tete = (*courant).suiv;
free (courant);
courant= tete;
Dr.Fadoua Bouafif
1
2
3
Suppression selon le contenu du nœud (suite)
ASD II
30
Exemple: Suppression du nœud dont la valeur est 18.
Tête X
20 Z NIL
31
courant
18 W
precedent
Y
55
X Y Z W
courant
Libérer (courant);
Courant  (*courant).suiv
precedent  (*precedent).suiv
Courant (*tete).suiv
precedent  tete
Précédent
1
2
3
(*precedent).suiv  (*courant).suiv;
Dr.Fadoua Bouafif
Activité5
ASD II
31
Ecrire un sous programme « supprimer_donnée() » qui
permet de supprimer un nœud dont la valeur est donnée.
Dr.Fadoua Bouafif
Solution en algorithmique
ASD II
31
procedure supprimer_donnee (var tete: liste, x: entier)
var : precedent, courant: liste
début
// initialiser courant à tete
si ((*tete).val == x) alors
courant  tete
tete  (*courant).suiv
libérer (courant)
sinon
precedent  tete
courant  (*tete).suiv
tant que ((courant != NIL) ET ((*courant).val != x)) faire
precedent  courant
courant  (*courant).suiv
fin tant que
si ((*courant).val == x)
alors (*precedent).suiv  (*courant).suiv
libérer (courant) // libérer l'espace mémoire
sinon écrire (‘’ l’element n’existe pas’’)
fin si
Fin si
Fin
Solution en C
ASD II
32
void supprimer_donnee (liste* tete, int x)
{
Nœud * precedent, * courant;
// initialiser courant à tete
courant = *tete ;
if ((*(*tete)).val == info)
{ *tete= (*courant).suiv;
free (courant);
}
else
{ precedent = *tete;
courant= (*(*tete)).suiv;
while ((courant != NULL) && ((*courant).val != x))
{ precedent= courant;
courant = (*courant).suiv;
}
if ((*courant).val == x)
{ (*precedent).suiv = (*courant).suiv;
free (courant); // libérer l'espace mémoire
}
else
printf (‘’ l’element n’existe pas’’);
}
Dr.Fadoua Bouafif
Remarques
▶ La conservation de l’adresse du premier élément de la liste dans un pointeur (tete) est obligatoire parce qu’il
représente le point d’entré pour la manipulation de la liste.
▶ La suppression de toute la liste ou du premier élément, et l’insertion au début de la liste sont les seules
opérations possibles qui permettent de modifier l’adresse du premier élément de la liste.
▶ Les zones mémoires allouées pour la liste peuvent ne pas être contigües et donc la perte de la tête de la
liste entraine la perte de toute la liste.
▶ Les sous-programmes relatifs aux différentes insertions et suppressions d’un élément de la liste
peuvent être implémentés avec des procédures ou des fonctions.
Deux avantages sont apportés par la représentation dynamique des listes:
▶ L’allocation dynamique de la mémoire en utilisant les variables dynamiques
▶ La facilité d’opérer sur les éléments, puisqu’il suffit d’opérer sur les pointeurs et non sur les variables
elles mêmes
ASD II
39
1
Dr.Fadoua Bouafif
Les Listes Circulaires
Définition 43
ASD II
Y
25 Z
77
▶ Une liste circulaire est une liste particulière dont le dernier nœud pointe sur le premier
nœud.
▶ Dans une telle liste, les fonctions d’ajout et de suppression correspondent à ceux de
l’ajout et la suppression au milieu d’une liste simplement chainée.
▶ L’opération de recherche nécessite de fixer un drapeau qui permet d’arrêter la recherche
quand on retombe sur le nœud du départ, sinon ça sera une boucle infinie.
Drapeau
Dr.Fadoua Bouafif
34 X
X Y Z
Activité 6
ASD II
31
Ecrire un sous programme « Affiche_liste() » qui affiche
tous les éléments de la liste circulaire donnée
Dr.Fadoua Bouafif
Solution Activité 6
ASD II
31
Dr.Fadoua Bouafif
en C
Algorithmique
Procedure affiche_listeCirculaire(tete:liste)
Var darpeau, p:liste
Début
drapeautete
si (drapeau<>Nil alors)
écrire( (*drapeau).val))
p(*drapeau).suiv
tantque(p<>drapeau) faire
écrire( (*p).val))
p(*p).suiv
fintantque
finsi
Fin
Void affiche_listeCirculaire(liste tete)
{
liste darpeau, p;
drapeau=tete;
if (drapeau!=NULL)
{
printf("%d", (*drapeau).val));
p=(*drapeau).suiv;
while(p<>drapeau)
{
printf("%d", (*p).val));
p=(*p).suiv;
}
}
}
1
Dr.Fadoua Bouafif
Les Listes doublement Chainées
1. Définition
2. Déclaration
3. Création
4. Manipulation
Définition
ASD II
41
▶ Une liste doublement chainée est une liste d'éléments, ou l’accès au successeur et au
prédécesseur d’un élément est possible. Elle est aussi appelée liste à chainage double
▶ Chaque nœud de la liste est composé de trois champs:
▶ La valeur du nœud,
▶ L’adresse du nœud prédécesseur, et
▶ L’adresse du nœud successeur
▶ En absence d’un élément suivant ou précédent, le champ du pointeur référence la valeur
NIL (NULL).
Dr.Fadoua Bouafif
Définition (suite)
ASD II
42
NIL 33 Y
premier nœud
Queue: lien vers
le dernier nœud
Z
78
X NIL
56
Y
 Le parcours dans la liste doublement chainée se fait dans les deux sens, du début vers la
fin et vice versa.
Tout comme les listes simplement chainées, différentes opérations peuvent être appliquées
sur les listes doublement chainées.
Le prédécesseur de la tête de la liste est NIL (NULL) et le successeur de la queue de la liste
est NIL (NULL).
Tête: lien vers le
X Y Z
Déclaration
ASD II
41
Dr.Fadoua Bouafif
En C
En Algorithme
Typedef Struct
{
type_de_données valeur;
Struct Nœud * suiv ;
Struct Nœud * pred ;
} Nœud;
Type Nœud=enregistrement
valeur: type_de_données
suiv : ↑ nœud
pred :↑ nœud
Fin_Noeud
Syntaxe Déclaration
d’un nœud
Typedef Nœud * ListeD ;
Type ListeD : ↑ nœud
Déclaration d’une liste
Typedef Struct
{
int val;
struct Nœud * suiv;
struct Nœud * pred;
} Nœud;
Typedef Nœud *ListeD;
void main()
{
listeD *tete;
…….
}
Algorithme principal
Type
Nœud=enregistrement
val: entier
suiv: ↑ Nœud
pred: ↑ Nœud
Fin_Noeud
Type ListeD : ↑ Nœud
var : tete: liste
début
……
Fin
Exemple
Création d’une cellule
La création se fait à l’aide des fonctions d’allocation dynamique.
50
En C
En algorithme
Allouer un espace mémoire pour
un nouveau nœud
#include « stdlib.h »
malloc ()
Allouer ()
Nom
fonction
nouveau est un pointeur sur le
nouveau nœud à insérer
Nœud *nouveau;
nouveau: ↑ Nœud
Déclaration
Allouer un espace mémoire
nouveau=(Noued *) malloc(sizeof(Noued);
Allouer(nouveau)
Affecter une donnée au champ
val
(*nouveau).val = valeur;
(*nouveau).valvaleur
Affecter NIL (NULL) au champ
suiv
(*nouveau).suiv = NULL;
(*nouveau).pred = NULL;
(*nouveau).suivNIL
(*nouveau).predNIL
Dr. Fadoua.BOUAFIF
Libération d’une cellule
La libération se fait à l’aide des fonctions d’allocation dynamique
51
En C
En algorithme
libérer le noeud allouer
free ()
libérer ()
Nom fonction
libérer le noeud nouveau
free (nouveau);
libérer (nouveau)
Déclaration
Il ne faut pas oublier d’inclure la bibliothèque <stdlib.h> en C
Dr. Fadoua.BOUAFIF
Manipulation de la liste doublement chainée
▶ Les opérations de base sur les listes sont:
▶ Initialisation d’une liste à vide.
▶ Tester si la liste est vide ou non.
▶ Premier élément de la liste.
▶ Dernier élément de la liste.
▶ Insertion d’un nouveau élément (nœud) dans la liste (début, milieu, fin).
▶ Suppression d’un élément (nœud) de la liste (début, milieu, fin).
ASD II
10
Dr.Fadoua Bouafif
Manipulation de la liste simplement chainée (suite)
▶ D’autres opérations peuvent être appliquées sur les listes:
▶ Affichage des éléments d’une liste
▶ Inversion d’une liste
▶ Taille d’une liste
▶ Concaténation de deux listes
▶ Destruction d’une liste
▶ …
ASD II
11
Dr.Fadoua Bouafif
1
Dr.Fadoua Bouafif
Les Piles et les files
1
Dr.Fadoua Bouafif
Les Piles
1. Définition
2. Exemple d’applications
3. Traitement des piles
Définition
44
▶ Une pile est une suite des éléments qui présente une stratégie de gestion de données
particulière. Cette gestion est liée à la suppression et l’insertion des éléments à la pile qui
se fait uniquement à travers le sommet de la pile.
▶ Une pile est aussi appelée LIFO (Last In First Out) ou encore DAPS (Dernier Arrivé
Premier Servi).
ASD II
Empiler
Sommet 5ème arrivé: 15
4ème arrivé: 17
3ème arrivé: 4
2ème arrivé: 8
1er
arrivé: 5
Dépiler
Base de la pile Dr.Fadoua Bouafif
Exemples d’applications 45
▶ Mémoriser les pages visitées dans un navigateur Web.
▶ Évaluer les expressions arithmétiques.
▶ Implémenter la fonction «Annuler » en traitement de texte.
▶ Archivager les messages dans une boite e-mail.
▶ Etc.
ASD II
Dr.Fadoua Bouafif
Traitement des piles
48
ASD II
▶ Les opérations de base appliquées sur une pile sont:
▶ Initialiser: initialiser une pile à vide
▶ Estvide: tester si la pile est vide ou non
▶ Sommet: retourner le sommet (premier élément ) de la pile
▶ Taille: envoyer la taille (nombre d’éléments) de la pile
▶ Dépiler: retirer l’élément de sommet de la pile, si la pile n’est pas vide
▶ Empiler: ajouter un élément au sommet de la pile si la pile n’est pas saturée (dans
le cas d’une implémentation avec tableau)
Il faut toujours tester le débordement de taille lors des opérations empiler et dépiler selon
l’implémentation utilisée Dr.Fadoua Bouafif
Traitement des piles (suite)
46
ASD II
Le traitement des piles peut être faite selon deux façons:
1. A l ’aide des tableaux: Piles statiques
2. A l’aide des listes chainées: Piles Dynamiques
En algorithme En C
Dr.Fadoua Bouafif
Piles Statiques: Déclaration
46
ASD II
4 15
17
4
3
2
1 8
0 5
Sommet
Empiler Dépiler
Dr.Fadoua Bouafif
En C
En algorithmique
Typedef struct Pile
{
int sommet;
int Tab[N];
} Pile;
Pile P;
type Pile=enregistrement
sommet: entier
Tab:tableau[0…N-1]d’entier
finpile
Var P: Pile
 Déclarer une structure Pile:
 un tableau (d’entiers, de réelles, de caractères, …)
 l’indice du sommet de la pile
Activité 7
46
ASD II
Dr.Fadoua Bouafif
 Ecrire un sous programme qui permet d’ajouter un élément dans la pile
En C
En algorithmique
void Empiler(Pile *P, int x)
{
if ((*P).sommet>=N-1)
printf("la pile est pleine");
else
{
(*p).sommet= (*p).sommet +1
(*p).Tab[(*p).sommet]= x
}
}
Procedure Empiler(var p:Pile, int x)
Debut
si (p.sommet>=N-1) alors
ecrire (“la pile est pleine”)
sinon
p.sommet<-p.sommet +1
p.Tab[p.sommet]<- x
finsi
Fin
Activité 8
46
ASD II
Dr.Fadoua Bouafif
 Ecrire un sous programme qui permet de supprimer un élément de la pile
En C
En algorithmique
int depiler(Pile *P)
{
int x;
if ((*P).sommet<0)
printf("la pile est vide");
else
{
x= (*p).Tab[(*p).sommet];
(*p).sommet--;
}
}
fonction depiler(var P:Pile):entier
Var int x
Debut
si (p.sommet<0) alors
ecrire (“la pile est vide”)
sinon
x <- p.Tab[p.sommet]
p.sommet<-p.sommet -1
finsi
Fin
Piles dynamiques: Déclaration
47
Sommet
5ème arrivé
4ème arrivé
3ème arrivé
2ème arrivé
1er arrivé
Empiler
Dépiler
5
8
4
17
15
NULL
En C
En Algorithmique
Typedef struct noeud
{
type_de_données val;
struc t Nœud * suiv ;
} Nœud;
Typedef struct Pile
{
Noeud *sommet;
}Pile;
Pile P;
Type Nœ ud=enregistrement
val: type_de_données
suiv : ↑ Nœud
Fin_Noeud
Type Pile =enregistrement
sommet: ↑Nœud
finPile
Var : P: Pile
Activité 10 46
ASD II
Dr.Fadoua Bouafif
 Ecrire un
sous
programme
qui permet
d’ajouter
un élément
dans la pile
En C
En algorithmique
void Empiler(Pile *P, int x)
{ Nœud *nouveau;
nouveau=(Nœud *)malloc(sizeof(Nœud));
if(nouveau)
{
(*nouveau).val=x;
(*nouveau).suiv =NULL;
if((*P).sommet!=NULL)
{ (*nouveau).suiv =(*P).sommet;
(*P).sommet=nouveau;}
else
(*P).sommet=nouveau;
}
else
printf("espace insufaisantn")
}
Procedure Empiler(var P:Pile, int x)
Var nouveau:Pile
Debut
allouer(nouveau)
si (nouveau!=Nil) alors
*nouveau.val<-x
*nouveau.suiv<- Nil
si(P.sommet!=Nil) alors
*nouveau.suiv<-P.sommet
P.sommet<-nouveau
sinon
P.sommet<-nouveau
sinon
écrire("espace insufaisantn")
finSi
FinSi
Fin
Activité 11
46
ASD II
Dr.Fadoua Bouafif
 Ecrire un sous
programme
qui permet de
supprimer un
élément de la
pile
En C
En algorithmique
int depiler(Pile *P)
{
int x;
Nœud *elt;
if ((*P).sommet==NULL)
printf("la pile est vide");
else
{
elt=(*P).sommet;
x=(*elt).val;
(*p).sommet=(*elt).suiv;
free(elt);
}
}
fonction depiler(var P:Pile):entier
Var x:entier
elt:↑ Nœud
Debut
si (P.sommet==Nil) alors
ecrire (“la pile est vide”)
sinon
elt<-P.sommet
x<- (*elt).val
P.sommet<-*(P.sommet).suiv
Liberer(elt)
finsi
Fin
Remarques
46
ASD II
Dr.Fadoua Bouafif
 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
 La suppression d’une valeur à une pile dynamique revient à une
suppression en début de liste si l’on considère que le sommet est la tête de
la liste
1
Dr.Fadoua Bouafif
Les Files
1. Définition
2. Exemple d’applications
3. Traitement des Files
Définition
49
▶ Une file est une cas particulier d’une liste chainée
▶ Une file est appelée FIFO (First In First Out) ou encore PAPS (Premier Arrivé
Premier Servi).
ASD II
Supprimer
Défiler
5ème arrivé
4ème arrivé
3ème arrivé
2ème arrivé
1er arrivé
Ajouter
Enfiler
15
17
4
8
5
Dr.Fadoua Bouafif
Exemples d’applications 50
▶ Gérer les transactions dans un serveur (Exemple: Serveur d’impression);
▶ Gérer des processus dans un système d’exploitation;
▶ Gérer les messages en attente dans un commutateur de réseau téléphonique.
▶ Etc.
ASD II
Dr.Fadoua Bouafif
Traitement des Files
53
ASD II
▶ Les opérations de base appliquées sur une file sont:
▶ Initialiser: Initialiser une file a vide
▶ Est vide: tester si la File est vide ou non
▶ EstPleine: tester si la File est pleine ou non
▶ Défiler: retirer un élément de la file, si la file n’est pas vide (tête)
▶ Enfiler: ajouter un élément dans la file (queue)
Il faut toujours tester le débordement de taille lors des opérations enfiler et défiler selon
l’implémentation utilisée
Dr.Fadoua Bouafif
Traitement des Files (suite)
46
ASD II
Le traitement des Files peut être faite selon deux façons:
1. A l ’aide des tableaux: Files statiques
2. A l’aide des listes chainées: Files Dynamiques
En algorithme En C
Dr.Fadoua Bouafif
Files Statiques: Déclaration
51
ASD II
5 8 4 17 15
0 1 2 3 4
Défiler
Enfiler
 Déclarer une structure File:
 un tableau (d’entiers, de réelles, de caractères, …)
 l’indice de la tête de la File: tete
 l’indice de la queue de la File: queue
En C
En algorithmique
Typedef struct File
{
int tete;
Int queue;
int Tab[N];
} File;
File F;
type File=enregistrement
tete: entier
queue: entier
Tab:tableau[0…N-1]d’entier
finFile
Var F: File
Activité 12
46
ASD II
Dr.Fadoua Bouafif
 Ecrire un sous-programme qui permet d’ajouter un élément dans une file
En C
En algorithmique
void Enfiler(File *F, int x)
{
if ((*F). tete<(*F). queue et (*F). queue=N-1)
printf("la file est pleine");
else
{
(*F). queue= (*F). queue+1
(*F).Tab[(*F). queue]= x
}
}
Procedure Enfiler(var F:File, int x)
Debut
si (F.tete<F.queue et F. queue=N-1) alors
ecrire (“la File est pleine”)
sinon
F. queue<-F. queue+1
F.Tab[F. queue]<- x
finsi
Fin
Activité 13
46
ASD II
Dr.Fadoua Bouafif
 Ecrire un sous programme qui permet de supprimer un élément de la file
En C
En algorithmique
int defiler(File *F)
{
int x;
if ((*F). tete>=(*F). queue)
printf("la file est vide");
else
{
x= (*F).Tab[(*F). tete];
(*F). tete++;
}
}
fonction defiler(var F:File):entier
Var int x
Debut
si (F. tete>=F. queue) alors
ecrire (“la file est vide”)
sinon
x <- F.Tab[F. tete]
F. tete<-F. tete+1
finsi
Fin
52
ASD II
en C
En algorithme
Typedef struct
{
type_de_données val;
struct Nœud * suiv ;
} Noeud;
Typedef struct File
{
Nœud *tete, *queue;
}File;
File F;
Type Nœud=enregistrement
val: type_de_données
suiv : ↑ Nœud
Fin_Noeud
Type File =enregistement
tete, queue: ↑ Nœud
Fin File
Var F:File
Queue
Tête
Défiler 5ème arrivé
4ème arrivé
3ème arrivé
2ème arrivé
1er arrivé
Enfiler
5 8 4 17 15 NULL
Files dynamiques: Déclaration
Activité 14 46
ASD II
Dr.Fadoua Bouafif
 Ecrire un sous
programme qui
permet d’ajouter
un élément dans
une File
En C
En algorithmique
void Empiler(File *F, int x)
{ Nœud *nouveau;
nouveau=(Nœud *)malloc(sizeof(Nœud));
if(nouveau)
{
(*nouveau).val=x;
(*nouveau).suiv =NULL;
if((*F).queue==NULL)
{ (*F).tete=nouveau ;
(*F).queue=nouveau;
}
else
(*(*F).queue)).suiv=nouveau;
}
else
printf("espace insufaisantn")
}
Procedure Empiler(var F:File, int
x)
Var nouveau:File
Debut
allouer(nouveau)
si (nouveau!=Nil) alors
*nouveau.val<-x
*nouveau.suiv<- NIL
si(F.queue==Nil) alors
F.tete<-nouveau
F.queue<-nouveau
sinon
*(F.queue).suiv<-
nouveau
finsi
sinon
écrire("espace insufaisantn")
Fin
Activité 15
46
ASD II
Dr.Fadoua Bouafif
 Ecrire un sous
programme
qui permet de
supprimer un
élément de la
File
En C
En algorithmique
int defiler(File *F)
{
int x;
Nœud *elt;
if ((*F).queue==NULL)
printf("la file est vide");
else
{
elt=(*F).tete;
x=(*elt).val;
(*F).tete=(*(*F).tete).suiv;
free(elt);
}
}
fonction defiler(var F:File):entier
Var x:entier
elt:↑ Nœud
Debut
si (F.queue==Nil) alors
ecrire (“la file est vide”)
sinon
elt<-F.tete
x<- (*elt).val
F.tete<-*(F.tete).suiv
Liberer(elt)
finsi
Fin
Conclusion
54
▶ Un tableau permet de représenter efficacement un ensemble de valeurs, dont la taille
est fixée à l’avance.
▶ Les problèmes d’allocation de mémoire relative à la structure tableau (espace
insuffisant ou superflu) sont résolus à travers l’utilisation de la structure dynamique,
liste chainée.
▶ Les opérations d’insertion et de suppression d’un élément sont plus faciles à implanter
avec la structure liste, par rapport à la structure tableau.
ASD II
Dr.Fadoua Bouafif
Conclusion
55
▶ Les piles et les files sont des cas particuliers de listes chainées (linéaires)
▶ Ces deux structures s’adaptent à certaines situations:
▶ Les piles sont le moyen le plus efficace pour exécuter les fonctions récursives
▶ Les files sont utilisées surtout dans les opérateurs d’E/S des périphériques de
l’ordinateur, ainsi que la gestion des problèmes de file d’attente
▶ Le choix de l’implémentation des piles ou des files dépend du cas qui se présente. Si le
volume d’information n’est pas important, l’implémentation contigüe est utile. Dans le
cas contraire, l’emploi des pointeurs est plus efficace pour économiser de l’espace
mémoire
ASD II
Dr.Fadoua Bouafif

Contenu connexe

Plus de FadouaBouafifSamoud

Ch2-Notions de base & actions élémentaires.pdf
Ch2-Notions de base & actions élémentaires.pdfCh2-Notions de base & actions élémentaires.pdf
Ch2-Notions de base & actions élémentaires.pdf
FadouaBouafifSamoud
 
Ch3-les structures conditionnelles.pdf
Ch3-les structures conditionnelles.pdfCh3-les structures conditionnelles.pdf
Ch3-les structures conditionnelles.pdf
FadouaBouafifSamoud
 
Ch4- les structures répétitives.pdf
Ch4- les structures répétitives.pdfCh4- les structures répétitives.pdf
Ch4- les structures répétitives.pdf
FadouaBouafifSamoud
 
Ch1-Généralités.pdf
Ch1-Généralités.pdfCh1-Généralités.pdf
Ch1-Généralités.pdf
FadouaBouafifSamoud
 
ch7_les chaines de caractères.pdf
ch7_les chaines de caractères.pdfch7_les chaines de caractères.pdf
ch7_les chaines de caractères.pdf
FadouaBouafifSamoud
 
ch6 les sous programmes.pdf
ch6 les sous programmes.pdfch6 les sous programmes.pdf
ch6 les sous programmes.pdf
FadouaBouafifSamoud
 
Ch5-les tableaux et les pointeurs.pdf
Ch5-les tableaux et les pointeurs.pdfCh5-les tableaux et les pointeurs.pdf
Ch5-les tableaux et les pointeurs.pdf
FadouaBouafifSamoud
 
ch3_les variables_dynamiques.pdf
ch3_les variables_dynamiques.pdfch3_les variables_dynamiques.pdf
ch3_les variables_dynamiques.pdf
FadouaBouafifSamoud
 
Ch2_ la récursivité.pdf
Ch2_ la récursivité.pdfCh2_ la récursivité.pdf
Ch2_ la récursivité.pdf
FadouaBouafifSamoud
 
Ch1 _ les enregistrements.pdf
Ch1 _ les enregistrements.pdfCh1 _ les enregistrements.pdf
Ch1 _ les enregistrements.pdf
FadouaBouafifSamoud
 

Plus de FadouaBouafifSamoud (10)

Ch2-Notions de base & actions élémentaires.pdf
Ch2-Notions de base & actions élémentaires.pdfCh2-Notions de base & actions élémentaires.pdf
Ch2-Notions de base & actions élémentaires.pdf
 
Ch3-les structures conditionnelles.pdf
Ch3-les structures conditionnelles.pdfCh3-les structures conditionnelles.pdf
Ch3-les structures conditionnelles.pdf
 
Ch4- les structures répétitives.pdf
Ch4- les structures répétitives.pdfCh4- les structures répétitives.pdf
Ch4- les structures répétitives.pdf
 
Ch1-Généralités.pdf
Ch1-Généralités.pdfCh1-Généralités.pdf
Ch1-Généralités.pdf
 
ch7_les chaines de caractères.pdf
ch7_les chaines de caractères.pdfch7_les chaines de caractères.pdf
ch7_les chaines de caractères.pdf
 
ch6 les sous programmes.pdf
ch6 les sous programmes.pdfch6 les sous programmes.pdf
ch6 les sous programmes.pdf
 
Ch5-les tableaux et les pointeurs.pdf
Ch5-les tableaux et les pointeurs.pdfCh5-les tableaux et les pointeurs.pdf
Ch5-les tableaux et les pointeurs.pdf
 
ch3_les variables_dynamiques.pdf
ch3_les variables_dynamiques.pdfch3_les variables_dynamiques.pdf
ch3_les variables_dynamiques.pdf
 
Ch2_ la récursivité.pdf
Ch2_ la récursivité.pdfCh2_ la récursivité.pdf
Ch2_ la récursivité.pdf
 
Ch1 _ les enregistrements.pdf
Ch1 _ les enregistrements.pdfCh1 _ les enregistrements.pdf
Ch1 _ les enregistrements.pdf
 

Dernier

Formation M2i - Onboarding réussi - les clés pour intégrer efficacement vos n...
Formation M2i - Onboarding réussi - les clés pour intégrer efficacement vos n...Formation M2i - Onboarding réussi - les clés pour intégrer efficacement vos n...
Formation M2i - Onboarding réussi - les clés pour intégrer efficacement vos n...
M2i Formation
 
Procédure consignation Lock Out Tag Out.pptx
Procédure consignation  Lock Out Tag Out.pptxProcédure consignation  Lock Out Tag Out.pptx
Procédure consignation Lock Out Tag Out.pptx
caggoune66
 
Newsletter SPW Agriculture en province du Luxembourg du 12-06-24
Newsletter SPW Agriculture en province du Luxembourg du 12-06-24Newsletter SPW Agriculture en province du Luxembourg du 12-06-24
Newsletter SPW Agriculture en province du Luxembourg du 12-06-24
BenotGeorges3
 
Iris van Herpen. pptx
Iris         van        Herpen.      pptxIris         van        Herpen.      pptx
Iris van Herpen. pptx
Txaruka
 
Burkina Faso library newsletter May 2024
Burkina Faso library newsletter May 2024Burkina Faso library newsletter May 2024
Burkina Faso library newsletter May 2024
Friends of African Village Libraries
 
Iris van Herpen. pptx
Iris         van         Herpen.      pptxIris         van         Herpen.      pptx
Iris van Herpen. pptx
Txaruka
 
Conseils pour Les Jeunes | Conseils de La Vie| Conseil de La Jeunesse
Conseils pour Les Jeunes | Conseils de La Vie| Conseil de La JeunesseConseils pour Les Jeunes | Conseils de La Vie| Conseil de La Jeunesse
Conseils pour Les Jeunes | Conseils de La Vie| Conseil de La Jeunesse
Oscar Smith
 
Iris van Herpen. pptx
Iris            van        Herpen.     pptxIris            van        Herpen.     pptx
Iris van Herpen. pptx
Txaruka
 
Edito-B1-francais Manuel to learning.pdf
Edito-B1-francais Manuel to learning.pdfEdito-B1-francais Manuel to learning.pdf
Edito-B1-francais Manuel to learning.pdf
WarlockeTamagafk
 
Cycle de Formation Théâtrale 2024 / 2025
Cycle de Formation Théâtrale 2024 / 2025Cycle de Formation Théâtrale 2024 / 2025
Cycle de Formation Théâtrale 2024 / 2025
Billy DEYLORD
 
Formation Intelligence Artificielle pour dirigeants- IT6-DIGITALIX 24_opt OK_...
Formation Intelligence Artificielle pour dirigeants- IT6-DIGITALIX 24_opt OK_...Formation Intelligence Artificielle pour dirigeants- IT6-DIGITALIX 24_opt OK_...
Formation Intelligence Artificielle pour dirigeants- IT6-DIGITALIX 24_opt OK_...
cristionobedi
 

Dernier (11)

Formation M2i - Onboarding réussi - les clés pour intégrer efficacement vos n...
Formation M2i - Onboarding réussi - les clés pour intégrer efficacement vos n...Formation M2i - Onboarding réussi - les clés pour intégrer efficacement vos n...
Formation M2i - Onboarding réussi - les clés pour intégrer efficacement vos n...
 
Procédure consignation Lock Out Tag Out.pptx
Procédure consignation  Lock Out Tag Out.pptxProcédure consignation  Lock Out Tag Out.pptx
Procédure consignation Lock Out Tag Out.pptx
 
Newsletter SPW Agriculture en province du Luxembourg du 12-06-24
Newsletter SPW Agriculture en province du Luxembourg du 12-06-24Newsletter SPW Agriculture en province du Luxembourg du 12-06-24
Newsletter SPW Agriculture en province du Luxembourg du 12-06-24
 
Iris van Herpen. pptx
Iris         van        Herpen.      pptxIris         van        Herpen.      pptx
Iris van Herpen. pptx
 
Burkina Faso library newsletter May 2024
Burkina Faso library newsletter May 2024Burkina Faso library newsletter May 2024
Burkina Faso library newsletter May 2024
 
Iris van Herpen. pptx
Iris         van         Herpen.      pptxIris         van         Herpen.      pptx
Iris van Herpen. pptx
 
Conseils pour Les Jeunes | Conseils de La Vie| Conseil de La Jeunesse
Conseils pour Les Jeunes | Conseils de La Vie| Conseil de La JeunesseConseils pour Les Jeunes | Conseils de La Vie| Conseil de La Jeunesse
Conseils pour Les Jeunes | Conseils de La Vie| Conseil de La Jeunesse
 
Iris van Herpen. pptx
Iris            van        Herpen.     pptxIris            van        Herpen.     pptx
Iris van Herpen. pptx
 
Edito-B1-francais Manuel to learning.pdf
Edito-B1-francais Manuel to learning.pdfEdito-B1-francais Manuel to learning.pdf
Edito-B1-francais Manuel to learning.pdf
 
Cycle de Formation Théâtrale 2024 / 2025
Cycle de Formation Théâtrale 2024 / 2025Cycle de Formation Théâtrale 2024 / 2025
Cycle de Formation Théâtrale 2024 / 2025
 
Formation Intelligence Artificielle pour dirigeants- IT6-DIGITALIX 24_opt OK_...
Formation Intelligence Artificielle pour dirigeants- IT6-DIGITALIX 24_opt OK_...Formation Intelligence Artificielle pour dirigeants- IT6-DIGITALIX 24_opt OK_...
Formation Intelligence Artificielle pour dirigeants- IT6-DIGITALIX 24_opt OK_...
 

ch4_les listes.pdf

  • 1. 1 Algorithmique & structures des données II 1ère Business Computing (BC) Responsable : Dr. Fadoua Bouafif Dr.Fadoua Bouafif
  • 2. 1 Chapitre 4 Les listes chainées Dr.Fadoua Bouafif
  • 3. Objectifs du chapitre Dr.Fadoua Bouafif A la fin du chapitre, les étudiants seront en mesure de: - Définir une liste chainée en algorithmique et en langage C - Déterminer la nécessité de la liste chainée pour la résolution des problèmes - Nommer les opérations de manipulation de la liste chainée - Distinguer les différents types de listes chainées
  • 4. Plan du chapitre 1. Introduction 2. Les listes chainées simples 3. Les listes circulaires 4. Les listes doublement chainées 5. Les piles et les files 6. Conclusion Dr.Fadoua Bouafif
  • 5. Introduction 3 Pour stocker un ensemble de données de même type d’une façon linéaire, les tableaux sont utilisés. Plusieurs inconvénients se présentent pour cette structure : 1)La capacité de stockage d’un tableau est fixe  problèmes quand le nombre de données à stocker est dynamique; 2) Les cases d’un tableau sont contigües  manque d’efficacité au niveau de la réservation de l’espace mémoire nécessaire; 3) L’ajout et la suppression d’un élément dans un tableau nécessitent des opérations de décalage de cases souvent coûteuses. Prévoir une structure de données qui évite ce type d’inconvénients  listes chaînées Dr.Fadoua Bouafif
  • 6. Introduction ASD II 4 - La liste chainée peut contenir des éléments de types simples ou complexes - Il existe différent types de listes chainées : - Simple - Double - Circulaire - D’autres structures sont définies en se basant sur les listes comme les piles et les files. Dr.Fadoua Bouafif
  • 7. 1 Dr.Fadoua Bouafif Les Listes Chainées Simples 1. Définition 2. Déclaration 3. Création 4. Manipulation
  • 8. Définition Une liste est une suite d’éléments, appelés cellules ou nœuds contenant chacune une zone de données et une zone de chaînage (adresse) de l’élément suivant dans la liste.  Tout élément de la liste (sauf le premier et le dernier) possède un successeur et un prédécesseur. 5 Chainage Lien vers le nœud suivant Données Chainage Lien vers le nœud suivant Données Données Chainage Lien vers le nœud suivant Tête: pointe sur le premier nœ ud Queue: pointe sur le NULL NIL  Le premier élément de la liste est nommé tête. C’est un pointeur qui contient l’adresse du premier nœud de la liste.  Le dernier élément de la liste est nommée queue. Il pointe sur NIL(NULL). Dr.Fadoua Bouafif
  • 9. Définition (suite) ASD II 6 ▶ L’utilisation des pointeurs facilite la manipulation des listes. ▶ Les éléments de la liste ne sont pas contigus en mémoire : chaque nœud est référencé par une adresse représentée par un pointeur Exemple: une liste d’entiers ▶ Il suffit de connaître la tête pour y pouvoir accéder aux différents autres éléments ▶ Le parcours est unidirectionnel et s’effectue de gauche à droite. ▶ Si la tête pointe sur le NULL, alors la liste est vide. Dr.Fadoua Bouafif
  • 10. Déclaration ASD II 7 En C En Algorithme Typedef Struct { type_de_données valeur; Struct Nœud * suivant; } Nœud; Type Nœud=enregistrement valeur: type_de_données suivant : ↑ nœud Fin_Noeud Syntaxe Déclaration d’un nœud Typedef Nœud * liste; Type liste: ↑ Nœud Syntaxe Déclaration d’une liste Typedef Struct { int val; struct Nœud * suiv; } Nœud; Typedef Noeud *liste; intmain() { liste tete; //Nœud *tete; ………… return 0; } Algorithme test Type Nœud=enregistrement val: entier suiv: ↑ Nœud Fin_Noeud Typeliste : ↑ Nœud var : tete: liste début ………. Fin Exemple val suiv Nœud
  • 11. Création d’une cellule La création se fait à l’aide des fonctions d’allocation dynamique. 11 En C En algorithme Allouer un espace mémoire pour un nouveau nœud #include « stdlib.h » malloc () Allouer () Nom fonction nouveau est un pointeur sur le nouveau nœud à insérer Nœud *nouveau; nouveau: ↑ Nœud Déclaration Allouer un espace mémoire nouveau=(Noued *) malloc(sizeof(Noued); Allouer(nouveau) Affecter une donnée au champ val (*nouveau).val = valeur; (*nouveau).valvaleur Affecter NIL (NULL) au champ suiv (*nouveau).suiv = NULL; (*nouveau).suivNIL Dr. Fadoua.BOUAFIF
  • 12. Libération d’une cellule La libération se fait à l’aide des fonctions d’allocation dynamique 12 En C En algorithme libérer le noeud allouer free () libérer () Nom fonction libérer le noeud nouveau free (nouveau); libérer (nouveau) Déclaration Il ne faut pas oublier d’inclure la bibliothèque <stdlib.h> en C Dr. Fadoua.BOUAFIF
  • 13. Manipulation de la liste simplement chainée ▶ Les opérations de base sur les listes sont: ▶ Initialisation d’une liste à vide. ▶ Tester si la liste est vide ou non. ▶ Premier élément de la liste. ▶ Dernier élément de la liste. ▶ Insertion d’un nouveau élément (nœud) dans la liste (début, milieu, fin). ▶ Suppression d’un élément (nœud) de la liste (début, milieu, fin). ASD II 10 Dr.Fadoua Bouafif
  • 14. Manipulation de la liste simplement chainée (suite) ▶ D’autres opérations peuvent être appliquées sur les listes: ▶ Affichage des éléments d’une liste ▶ Inversion d’une liste ▶ Taille d’une liste ▶ Concaténation de deux listes ▶ Destruction d’une liste ▶ … ASD II 11 Dr.Fadoua Bouafif
  • 15. Activité1 ASD II 25 Ecrire un sous programme "Affiche()" qui permet d’afficher le contenu d’une liste simplement chainée d’entiers. Dr.Fadoua Bouafif
  • 16. Solution de l’activité 1 ASD II 27 } Dr.Fadoua Bouafif En C En algorithmique Procédure Affiche (tete: liste) var: courant : liste Début courant  tete si(courant== NIL) alors écrire (‘’la liste est vide’’) sinon écrire (‘’Contenu de la liste:’) tant que (courant != NIL) faire écrire ((*courant).val, " → " ) courant  (*courant).suiv fin tant que fin si Fin void affiche (liste tete) { liste courant = tete; if (courant == NULL) printf ("nLa liste est viden"); else { printf ("nContenu de la liste: "); // Parcourir toute la liste while (courant != NULL) { printf (" %d n", (*courant).val); courant = (*courant).suiv; } } }
  • 17. Insertion d’un nouveau nœud Etape 1: Créer le nouveau nœud ▶ Pour insérer un nouveau élément dans une liste, il faut tout d’abord créer un nouveau nœud ASD II 12 suiv val nouveau 1. Déc lara tion 2. Allocation 3. Initialisation des champs (valeur et suivant) nouveau: ↑ nœud Allouer(nouveau) (*nouveau).val valeur (*nouveau).suiv  NIL
  • 18. Insertion d’un nouveau nœud ▶ Trois cas sont possibles pour insérer un nœud dans une liste simplement chainée ASD II 13 2ffx04 259 2ffx08 321 Tête 98 NULL 2ffx00 2ffx04 2ffx08 2ffx00 Insertion au début Insertion au milieu Insertion à la fin Dr.Fadoua Bouafif
  • 19. Insertion d’un nouveau nœud ▶ Trois cas sont possibles pour insérer un nœud dans une liste simplement chainée ASD II 14 259 Y Z 321 Tête 98 NULL X Y Z X Insertion au début Insertion au milieu Insertion à la fin Remarque:les lettres en majuscule représentent les adressesdes nœuds
  • 20. Insertion début Etape 2: Insérer le nouveau nœud ▶ Il faut distinguer deux cas: (1) liste vide et (2) liste non-vide. ASD II 15 Tête NULL NULL Nouveau valeur X Tête X NULL Nouveau valeur X tete = nouveau; Cas 1: Liste vide: Avant insertion Cas 1: Liste vide: Après insertion Dr.Fadoua Bouafif
  • 21. Insertion début ▶ Etape 2: Insérer le nouveau nœud ▶ Il faut distinguer deux cas: (1) liste vide et (2) liste non-vide. 16 Cas 2: Liste non-vide: Avant insertion NIL info Nouveau W Cas 2: Liste non-vide: Après insertion 10 Y 7 Z 18 NIL X Y Z Tête X info Nouveau W 10 Y 7 Z 18 NIL X Y Z Tête (*nouveau).suiv = tete; tete = nouveau; Tête Dr.Fadoua Bouafif
  • 22. Activité2 Ecrire un sous-programme « insertionTête() »qui permet d’ajouter un entier donné au début d’une liste Dr.Fadoua Bouafif
  • 23. Insertion début En C En algorithme void inserer_debut (liste *tete, int info) {// declaration et allocation Nœud *nouveau; nouveau = (Noeud *) malloc (sizeof(Noeud)); if(nouveau) { (*nouveau).val = info; // affectation (*nouveau).suiv = NULL; if (*tete == NULL) // la liste est vide *tete = nouveau; else // la liste n’est pas vide { (*nouveau).suiv =*tete; *tete = nouveau; } } } Procedure inserer_debut (var tete: liste, info: entier) Var: nouveau: ↑ Nœud Debut Alouer (nouveau) (*nouveau).valinfo (*nouveau).suivNIL Si (tete==NIL) alors tete nouveau sinon (*nouveau).suiv tete tete  nouveau fin si Fin
  • 24. Insertion fin ASD II 18 L’insertion à la fin correspond à une insertion après le dernier nœud. Nous distinguons deux cas: • Cas 1: Liste vide Quand une liste vide, l’insertion au début et celle à la fin sont équivalentes puisque le nouveau nœud sera l’unique nœud de la liste. • Cas 2: Liste non-vide Il faut parcourir toute la liste pour accéder au dernier nœud après lequel le nouveau nœud sera inséré. Pour parcourir une liste, nous avons besoin d’un pointeur « courant » qui va parcourir la liste jusqu’à ce qu’il pointe sur le dernier nœud dont le champ « suiv » est égal à NIL
  • 25. Insertion fin ASD II 19 NIL info Nouveau W 10 Y 7 Z NIL 18 X Y Z T ête X courant courant Etape 2: Lier le nouveau nœud au dernier nœud en utilisant « courant ». 10 Y 7 Z 18 X Y Z T ête X courant Cas 2: Liste non-vide Il faut parcourir toute la liste pour accéder au dernier nœud après lequel le nouveau nœud (*courant).suiv = nouveau; sera inséré. Etape 1: Parcourir la liste nœud par nœud par le pointeur « courant ». courant  (*courant).suiv; NIL
  • 26. Activité 3 Ecrire un sous-programme « insertionFin() »qui permet d’ajouter un entier donné à la fin d’une liste Dr.Fadoua Bouafif
  • 27. ASD II ertion fin 20 Ins En C En algorithme void inserer_fin (liste * tete, int info) { Noeud * nouveau; // nouveau nœud à insérer Noeud * courant; // nœud courant nouveau = (Noeud *) malloc (sizeof (Noeud)); (*nouveau).val = info; (*nouveau).suiv = NULL; if (*tete == NULL) // Si la liste est vide, nous créons un premier nœud *tete = nouveau; else // Si la liste n’est pas vide { // Parcourir la liste jusqu'au dernier nœud courant = *tete; // Initialiser le courant à la tête de la liste while ((*courant).suiv != NULL) { courant = (*courant).suiv; } // Lier le nouveau noeud à la fin de la liste (*courant).suiv = nouveau; } } Procedure inserer_fin (var tete: liste, info: entier) Var: nouveau, courant: ↑ Nœud Debut Alouer (nouveau) (*nouveau).valinfo (*nouveau).suiv  NIL Si(tete==NIL) alors tete nouveau sinon courant tete Tant que ((*courant).suiv != NIL) faire courant  (*courant).suiv Fin tant que (*courant).suiv  nouveau fin si Fin Dr.Fadoua Bouafif
  • 28. Insertion à une position donnée ASD II 21 Principe Soit pos la position donnée : 1) Si (pos == 1), alors c’est le cas de l’insertion au début de la liste 2) Si (pos > 1), alors deux pointeurs seront nécessairement définit: - Pointeur courant, positionné sur le nœud à la position pos, et - Pointeur precedent, positionné sur le nœud à la position (pos-1). Afin de réaliser l’insertion du nœud désiré, il faut:  lier le nœud à la position (pos-1) (pointé par precedent) au nouveau nœud;  et après lier le nouveau nœud au nœud à la position (pos) (pointé par courant) Dr.Fadoua Bouafif
  • 29. Insertion à une position donnée ASD II 22 55 Y X Tête X 20 Z Y T 18 Z 31 NIL T courant precedent 72 Nouveau W (*precedent).suiv  nouveau Exemple: Insérer le nœud 72 à la 3ème position (pos == 3). courant precedent Courant  (*courant).suiv precedent  courant (*nouveau).suiv  courant Courant (*tete).suiv precedent  tete NULL 20 Z courant 18 T Y precedent 72 W W Nouveau Z 1 2 3 Dr.Fadoua Bouafif
  • 30. Insertion à une position donnée en Algorithmique ASD II 23 Procedure inserer_debut (var tete: liste, info: entier) Procedure inserer_position (var tete: liste, info: entier, pos: entier) var: i: entier nouveau, precedent, courant: ↑ Noeud Début Allouer (nouveau) (*nouveau).valinfo // Allocation du noeud à insérer (*nouveau).suiv  NIL Si (pos == 1) alors inserer_debut (tete, info) sinon si (pos >1) alors courant (*tete).suiv precedent  tete i  1 tant que ((courant != NIL) ET (i != (pos-1))) faire precedent  courant courant  (*courant).suiv i++ fin tant que si ((pos-1) == i) // Réaliser l'insertion alors (*precedent).suiv  nouveau (*nouveau).suiv  courant sinon écrire (‘’position erronée’’) fin si sinon écrire (‘’position erronée’’) fin si fin si Fin
  • 31. Insertion à une position donnée En C ASD II 24 void inserer_debut (liste *tete, int info); void inserer_position (liste *tete, int info, int pos) { int i; Noeud *nouveau, *precedent, *courant; // Allocation du noeud à insérer nouveau = (struct noeud*) malloc (sizeof (struct noeud)); If (nouveau){ (*nouveau).val = info; (*nouveau).suiv = NULL; if (pos == 1) inserer_debut (tete, info); else { if (pos >1) { courant = (*(*tete)).suiv; precedent= *tete; i = 1; While ((courant) && (i != (pos-1))) { precedent = courant; courant = (*courant).suiv; i++; } if ((pos-1) == i) // Réaliser l'insertion { (*precedent).suiv = nouveau; (*nouveau).suiv = courant; } else printf (‘’position erronée’’); } else printf (‘’position erronée’’); } }}
  • 32. Activité 4 Ecrire un sous-programme « insertion()»qui permet d’ajouter un entier donné à une liste triée Dr.Fadoua Bouafif
  • 33. Insertion une donnée à une liste triée en Algorithmique ASD II 23 Procedure inserer_debut (var tete: liste, info: entier) Procedure inserer_contenue (var tete: liste, x: entier) var: i: entier nouveau, precedent, courant: ↑ Noeud Début Allouer (nouveau) (*nouveau).valx // Allocation du noeud à insérer (*nouveau).suiv  NIL Si (x >= (*tete).valeur alors inserer_debut (tete,x) sinon courant (*tete).suiv precedent  tete tant que ((courant != NIL) ET (x<*courant.val)) faire precedent  courant courant  (*courant).suiv fin tant que si (x>=*courant.val) // Réaliser l'insertion alors (*precedent).suiv  nouveau (*nouveau).suiv  courant fin si fin si Fin
  • 34. Insertion une donnée à une liste triée En C ASD II 24 void inserer_debut (liste *tete, int info); void inserer_listeTriee (liste *tete, int x) { int i; Noeud *nouveau, *precedent, *courant; // Allocation du noeud à insérer nouveau = (struct noeud*) malloc (sizeof (struct noeud)); If (nouveau){ (*nouveau).val = x; (*nouveau).suiv = NULL; if (x >= (*tete).val inserer_debut (tete, x); else { courant = (*(*tete)).suiv; precedent= *tete; While ((courant) && (x<*courant.val)) { precedent = courant; courant = (*courant).suiv; } if (x>=*courant.val) // Réaliser l'insertion { (*precedent).suiv = nouveau; (*nouveau).suiv = courant; } } }
  • 35. Suppression d’une cellule ASD II 28 La suppression d’un nœud peut se faire sur la base du contenu du nœud ou de sa position. Dans les deux cas, nous avons besoin des deux pointeurs: 1) courant: positionné sur le nœud à supprimer, et 2) precedent: positionné sur le nœud qui précède le nœud à supprimer. Le principe de la suppression est de lier le nœud précédent au nœud suivant et par la suite libérer (supprimer) le nœud courant. Dr.Fadoua Bouafif
  • 36. Suppression selon le contenu du nœud ASD II 29 Y 55 X Tête X Z 20 Y W 18 Z NULL 31 W courant Tête Y Si le nœud à supprimer est le premier nœud de la liste, alors la tête avance vers le deuxième nœud et nous libérons le premier nœud. Exemple: Supprimer 55. tete = (*courant).suiv; free (courant); courant= tete; Dr.Fadoua Bouafif 1 2 3
  • 37. Suppression selon le contenu du nœud (suite) ASD II 30 Exemple: Suppression du nœud dont la valeur est 18. Tête X 20 Z NIL 31 courant 18 W precedent Y 55 X Y Z W courant Libérer (courant); Courant  (*courant).suiv precedent  (*precedent).suiv Courant (*tete).suiv precedent  tete Précédent 1 2 3 (*precedent).suiv  (*courant).suiv; Dr.Fadoua Bouafif
  • 38. Activité5 ASD II 31 Ecrire un sous programme « supprimer_donnée() » qui permet de supprimer un nœud dont la valeur est donnée. Dr.Fadoua Bouafif
  • 39. Solution en algorithmique ASD II 31 procedure supprimer_donnee (var tete: liste, x: entier) var : precedent, courant: liste début // initialiser courant à tete si ((*tete).val == x) alors courant  tete tete  (*courant).suiv libérer (courant) sinon precedent  tete courant  (*tete).suiv tant que ((courant != NIL) ET ((*courant).val != x)) faire precedent  courant courant  (*courant).suiv fin tant que si ((*courant).val == x) alors (*precedent).suiv  (*courant).suiv libérer (courant) // libérer l'espace mémoire sinon écrire (‘’ l’element n’existe pas’’) fin si Fin si Fin
  • 40. Solution en C ASD II 32 void supprimer_donnee (liste* tete, int x) { Nœud * precedent, * courant; // initialiser courant à tete courant = *tete ; if ((*(*tete)).val == info) { *tete= (*courant).suiv; free (courant); } else { precedent = *tete; courant= (*(*tete)).suiv; while ((courant != NULL) && ((*courant).val != x)) { precedent= courant; courant = (*courant).suiv; } if ((*courant).val == x) { (*precedent).suiv = (*courant).suiv; free (courant); // libérer l'espace mémoire } else printf (‘’ l’element n’existe pas’’); } Dr.Fadoua Bouafif
  • 41. Remarques ▶ La conservation de l’adresse du premier élément de la liste dans un pointeur (tete) est obligatoire parce qu’il représente le point d’entré pour la manipulation de la liste. ▶ La suppression de toute la liste ou du premier élément, et l’insertion au début de la liste sont les seules opérations possibles qui permettent de modifier l’adresse du premier élément de la liste. ▶ Les zones mémoires allouées pour la liste peuvent ne pas être contigües et donc la perte de la tête de la liste entraine la perte de toute la liste. ▶ Les sous-programmes relatifs aux différentes insertions et suppressions d’un élément de la liste peuvent être implémentés avec des procédures ou des fonctions. Deux avantages sont apportés par la représentation dynamique des listes: ▶ L’allocation dynamique de la mémoire en utilisant les variables dynamiques ▶ La facilité d’opérer sur les éléments, puisqu’il suffit d’opérer sur les pointeurs et non sur les variables elles mêmes ASD II 39
  • 43. Définition 43 ASD II Y 25 Z 77 ▶ Une liste circulaire est une liste particulière dont le dernier nœud pointe sur le premier nœud. ▶ Dans une telle liste, les fonctions d’ajout et de suppression correspondent à ceux de l’ajout et la suppression au milieu d’une liste simplement chainée. ▶ L’opération de recherche nécessite de fixer un drapeau qui permet d’arrêter la recherche quand on retombe sur le nœud du départ, sinon ça sera une boucle infinie. Drapeau Dr.Fadoua Bouafif 34 X X Y Z
  • 44. Activité 6 ASD II 31 Ecrire un sous programme « Affiche_liste() » qui affiche tous les éléments de la liste circulaire donnée Dr.Fadoua Bouafif
  • 45. Solution Activité 6 ASD II 31 Dr.Fadoua Bouafif en C Algorithmique Procedure affiche_listeCirculaire(tete:liste) Var darpeau, p:liste Début drapeautete si (drapeau<>Nil alors) écrire( (*drapeau).val)) p(*drapeau).suiv tantque(p<>drapeau) faire écrire( (*p).val)) p(*p).suiv fintantque finsi Fin Void affiche_listeCirculaire(liste tete) { liste darpeau, p; drapeau=tete; if (drapeau!=NULL) { printf("%d", (*drapeau).val)); p=(*drapeau).suiv; while(p<>drapeau) { printf("%d", (*p).val)); p=(*p).suiv; } } }
  • 46. 1 Dr.Fadoua Bouafif Les Listes doublement Chainées 1. Définition 2. Déclaration 3. Création 4. Manipulation
  • 47. Définition ASD II 41 ▶ Une liste doublement chainée est une liste d'éléments, ou l’accès au successeur et au prédécesseur d’un élément est possible. Elle est aussi appelée liste à chainage double ▶ Chaque nœud de la liste est composé de trois champs: ▶ La valeur du nœud, ▶ L’adresse du nœud prédécesseur, et ▶ L’adresse du nœud successeur ▶ En absence d’un élément suivant ou précédent, le champ du pointeur référence la valeur NIL (NULL). Dr.Fadoua Bouafif
  • 48. Définition (suite) ASD II 42 NIL 33 Y premier nœud Queue: lien vers le dernier nœud Z 78 X NIL 56 Y  Le parcours dans la liste doublement chainée se fait dans les deux sens, du début vers la fin et vice versa. Tout comme les listes simplement chainées, différentes opérations peuvent être appliquées sur les listes doublement chainées. Le prédécesseur de la tête de la liste est NIL (NULL) et le successeur de la queue de la liste est NIL (NULL). Tête: lien vers le X Y Z
  • 49. Déclaration ASD II 41 Dr.Fadoua Bouafif En C En Algorithme Typedef Struct { type_de_données valeur; Struct Nœud * suiv ; Struct Nœud * pred ; } Nœud; Type Nœud=enregistrement valeur: type_de_données suiv : ↑ nœud pred :↑ nœud Fin_Noeud Syntaxe Déclaration d’un nœud Typedef Nœud * ListeD ; Type ListeD : ↑ nœud Déclaration d’une liste Typedef Struct { int val; struct Nœud * suiv; struct Nœud * pred; } Nœud; Typedef Nœud *ListeD; void main() { listeD *tete; ……. } Algorithme principal Type Nœud=enregistrement val: entier suiv: ↑ Nœud pred: ↑ Nœud Fin_Noeud Type ListeD : ↑ Nœud var : tete: liste début …… Fin Exemple
  • 50. Création d’une cellule La création se fait à l’aide des fonctions d’allocation dynamique. 50 En C En algorithme Allouer un espace mémoire pour un nouveau nœud #include « stdlib.h » malloc () Allouer () Nom fonction nouveau est un pointeur sur le nouveau nœud à insérer Nœud *nouveau; nouveau: ↑ Nœud Déclaration Allouer un espace mémoire nouveau=(Noued *) malloc(sizeof(Noued); Allouer(nouveau) Affecter une donnée au champ val (*nouveau).val = valeur; (*nouveau).valvaleur Affecter NIL (NULL) au champ suiv (*nouveau).suiv = NULL; (*nouveau).pred = NULL; (*nouveau).suivNIL (*nouveau).predNIL Dr. Fadoua.BOUAFIF
  • 51. Libération d’une cellule La libération se fait à l’aide des fonctions d’allocation dynamique 51 En C En algorithme libérer le noeud allouer free () libérer () Nom fonction libérer le noeud nouveau free (nouveau); libérer (nouveau) Déclaration Il ne faut pas oublier d’inclure la bibliothèque <stdlib.h> en C Dr. Fadoua.BOUAFIF
  • 52. Manipulation de la liste doublement chainée ▶ Les opérations de base sur les listes sont: ▶ Initialisation d’une liste à vide. ▶ Tester si la liste est vide ou non. ▶ Premier élément de la liste. ▶ Dernier élément de la liste. ▶ Insertion d’un nouveau élément (nœud) dans la liste (début, milieu, fin). ▶ Suppression d’un élément (nœud) de la liste (début, milieu, fin). ASD II 10 Dr.Fadoua Bouafif
  • 53. Manipulation de la liste simplement chainée (suite) ▶ D’autres opérations peuvent être appliquées sur les listes: ▶ Affichage des éléments d’une liste ▶ Inversion d’une liste ▶ Taille d’une liste ▶ Concaténation de deux listes ▶ Destruction d’une liste ▶ … ASD II 11 Dr.Fadoua Bouafif
  • 55. 1 Dr.Fadoua Bouafif Les Piles 1. Définition 2. Exemple d’applications 3. Traitement des piles
  • 56. Définition 44 ▶ Une pile est une suite des éléments qui présente une stratégie de gestion de données particulière. Cette gestion est liée à la suppression et l’insertion des éléments à la pile qui se fait uniquement à travers le sommet de la pile. ▶ Une pile est aussi appelée LIFO (Last In First Out) ou encore DAPS (Dernier Arrivé Premier Servi). ASD II Empiler Sommet 5ème arrivé: 15 4ème arrivé: 17 3ème arrivé: 4 2ème arrivé: 8 1er arrivé: 5 Dépiler Base de la pile Dr.Fadoua Bouafif
  • 57. Exemples d’applications 45 ▶ Mémoriser les pages visitées dans un navigateur Web. ▶ Évaluer les expressions arithmétiques. ▶ Implémenter la fonction «Annuler » en traitement de texte. ▶ Archivager les messages dans une boite e-mail. ▶ Etc. ASD II Dr.Fadoua Bouafif
  • 58. Traitement des piles 48 ASD II ▶ Les opérations de base appliquées sur une pile sont: ▶ Initialiser: initialiser une pile à vide ▶ Estvide: tester si la pile est vide ou non ▶ Sommet: retourner le sommet (premier élément ) de la pile ▶ Taille: envoyer la taille (nombre d’éléments) de la pile ▶ Dépiler: retirer l’élément de sommet de la pile, si la pile n’est pas vide ▶ Empiler: ajouter un élément au sommet de la pile si la pile n’est pas saturée (dans le cas d’une implémentation avec tableau) Il faut toujours tester le débordement de taille lors des opérations empiler et dépiler selon l’implémentation utilisée Dr.Fadoua Bouafif
  • 59. Traitement des piles (suite) 46 ASD II Le traitement des piles peut être faite selon deux façons: 1. A l ’aide des tableaux: Piles statiques 2. A l’aide des listes chainées: Piles Dynamiques En algorithme En C Dr.Fadoua Bouafif
  • 60. Piles Statiques: Déclaration 46 ASD II 4 15 17 4 3 2 1 8 0 5 Sommet Empiler Dépiler Dr.Fadoua Bouafif En C En algorithmique Typedef struct Pile { int sommet; int Tab[N]; } Pile; Pile P; type Pile=enregistrement sommet: entier Tab:tableau[0…N-1]d’entier finpile Var P: Pile  Déclarer une structure Pile:  un tableau (d’entiers, de réelles, de caractères, …)  l’indice du sommet de la pile
  • 61. Activité 7 46 ASD II Dr.Fadoua Bouafif  Ecrire un sous programme qui permet d’ajouter un élément dans la pile En C En algorithmique void Empiler(Pile *P, int x) { if ((*P).sommet>=N-1) printf("la pile est pleine"); else { (*p).sommet= (*p).sommet +1 (*p).Tab[(*p).sommet]= x } } Procedure Empiler(var p:Pile, int x) Debut si (p.sommet>=N-1) alors ecrire (“la pile est pleine”) sinon p.sommet<-p.sommet +1 p.Tab[p.sommet]<- x finsi Fin
  • 62. Activité 8 46 ASD II Dr.Fadoua Bouafif  Ecrire un sous programme qui permet de supprimer un élément de la pile En C En algorithmique int depiler(Pile *P) { int x; if ((*P).sommet<0) printf("la pile est vide"); else { x= (*p).Tab[(*p).sommet]; (*p).sommet--; } } fonction depiler(var P:Pile):entier Var int x Debut si (p.sommet<0) alors ecrire (“la pile est vide”) sinon x <- p.Tab[p.sommet] p.sommet<-p.sommet -1 finsi Fin
  • 63. Piles dynamiques: Déclaration 47 Sommet 5ème arrivé 4ème arrivé 3ème arrivé 2ème arrivé 1er arrivé Empiler Dépiler 5 8 4 17 15 NULL En C En Algorithmique Typedef struct noeud { type_de_données val; struc t Nœud * suiv ; } Nœud; Typedef struct Pile { Noeud *sommet; }Pile; Pile P; Type Nœ ud=enregistrement val: type_de_données suiv : ↑ Nœud Fin_Noeud Type Pile =enregistrement sommet: ↑Nœud finPile Var : P: Pile
  • 64. Activité 10 46 ASD II Dr.Fadoua Bouafif  Ecrire un sous programme qui permet d’ajouter un élément dans la pile En C En algorithmique void Empiler(Pile *P, int x) { Nœud *nouveau; nouveau=(Nœud *)malloc(sizeof(Nœud)); if(nouveau) { (*nouveau).val=x; (*nouveau).suiv =NULL; if((*P).sommet!=NULL) { (*nouveau).suiv =(*P).sommet; (*P).sommet=nouveau;} else (*P).sommet=nouveau; } else printf("espace insufaisantn") } Procedure Empiler(var P:Pile, int x) Var nouveau:Pile Debut allouer(nouveau) si (nouveau!=Nil) alors *nouveau.val<-x *nouveau.suiv<- Nil si(P.sommet!=Nil) alors *nouveau.suiv<-P.sommet P.sommet<-nouveau sinon P.sommet<-nouveau sinon écrire("espace insufaisantn") finSi FinSi Fin
  • 65. Activité 11 46 ASD II Dr.Fadoua Bouafif  Ecrire un sous programme qui permet de supprimer un élément de la pile En C En algorithmique int depiler(Pile *P) { int x; Nœud *elt; if ((*P).sommet==NULL) printf("la pile est vide"); else { elt=(*P).sommet; x=(*elt).val; (*p).sommet=(*elt).suiv; free(elt); } } fonction depiler(var P:Pile):entier Var x:entier elt:↑ Nœud Debut si (P.sommet==Nil) alors ecrire (“la pile est vide”) sinon elt<-P.sommet x<- (*elt).val P.sommet<-*(P.sommet).suiv Liberer(elt) finsi Fin
  • 66. Remarques 46 ASD II Dr.Fadoua Bouafif  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  La suppression d’une valeur à une pile dynamique revient à une suppression en début de liste si l’on considère que le sommet est la tête de la liste
  • 67. 1 Dr.Fadoua Bouafif Les Files 1. Définition 2. Exemple d’applications 3. Traitement des Files
  • 68. Définition 49 ▶ Une file est une cas particulier d’une liste chainée ▶ Une file est appelée FIFO (First In First Out) ou encore PAPS (Premier Arrivé Premier Servi). ASD II Supprimer Défiler 5ème arrivé 4ème arrivé 3ème arrivé 2ème arrivé 1er arrivé Ajouter Enfiler 15 17 4 8 5 Dr.Fadoua Bouafif
  • 69. Exemples d’applications 50 ▶ Gérer les transactions dans un serveur (Exemple: Serveur d’impression); ▶ Gérer des processus dans un système d’exploitation; ▶ Gérer les messages en attente dans un commutateur de réseau téléphonique. ▶ Etc. ASD II Dr.Fadoua Bouafif
  • 70. Traitement des Files 53 ASD II ▶ Les opérations de base appliquées sur une file sont: ▶ Initialiser: Initialiser une file a vide ▶ Est vide: tester si la File est vide ou non ▶ EstPleine: tester si la File est pleine ou non ▶ Défiler: retirer un élément de la file, si la file n’est pas vide (tête) ▶ Enfiler: ajouter un élément dans la file (queue) Il faut toujours tester le débordement de taille lors des opérations enfiler et défiler selon l’implémentation utilisée Dr.Fadoua Bouafif
  • 71. Traitement des Files (suite) 46 ASD II Le traitement des Files peut être faite selon deux façons: 1. A l ’aide des tableaux: Files statiques 2. A l’aide des listes chainées: Files Dynamiques En algorithme En C Dr.Fadoua Bouafif
  • 72. Files Statiques: Déclaration 51 ASD II 5 8 4 17 15 0 1 2 3 4 Défiler Enfiler  Déclarer une structure File:  un tableau (d’entiers, de réelles, de caractères, …)  l’indice de la tête de la File: tete  l’indice de la queue de la File: queue En C En algorithmique Typedef struct File { int tete; Int queue; int Tab[N]; } File; File F; type File=enregistrement tete: entier queue: entier Tab:tableau[0…N-1]d’entier finFile Var F: File
  • 73. Activité 12 46 ASD II Dr.Fadoua Bouafif  Ecrire un sous-programme qui permet d’ajouter un élément dans une file En C En algorithmique void Enfiler(File *F, int x) { if ((*F). tete<(*F). queue et (*F). queue=N-1) printf("la file est pleine"); else { (*F). queue= (*F). queue+1 (*F).Tab[(*F). queue]= x } } Procedure Enfiler(var F:File, int x) Debut si (F.tete<F.queue et F. queue=N-1) alors ecrire (“la File est pleine”) sinon F. queue<-F. queue+1 F.Tab[F. queue]<- x finsi Fin
  • 74. Activité 13 46 ASD II Dr.Fadoua Bouafif  Ecrire un sous programme qui permet de supprimer un élément de la file En C En algorithmique int defiler(File *F) { int x; if ((*F). tete>=(*F). queue) printf("la file est vide"); else { x= (*F).Tab[(*F). tete]; (*F). tete++; } } fonction defiler(var F:File):entier Var int x Debut si (F. tete>=F. queue) alors ecrire (“la file est vide”) sinon x <- F.Tab[F. tete] F. tete<-F. tete+1 finsi Fin
  • 75. 52 ASD II en C En algorithme Typedef struct { type_de_données val; struct Nœud * suiv ; } Noeud; Typedef struct File { Nœud *tete, *queue; }File; File F; Type Nœud=enregistrement val: type_de_données suiv : ↑ Nœud Fin_Noeud Type File =enregistement tete, queue: ↑ Nœud Fin File Var F:File Queue Tête Défiler 5ème arrivé 4ème arrivé 3ème arrivé 2ème arrivé 1er arrivé Enfiler 5 8 4 17 15 NULL Files dynamiques: Déclaration
  • 76. Activité 14 46 ASD II Dr.Fadoua Bouafif  Ecrire un sous programme qui permet d’ajouter un élément dans une File En C En algorithmique void Empiler(File *F, int x) { Nœud *nouveau; nouveau=(Nœud *)malloc(sizeof(Nœud)); if(nouveau) { (*nouveau).val=x; (*nouveau).suiv =NULL; if((*F).queue==NULL) { (*F).tete=nouveau ; (*F).queue=nouveau; } else (*(*F).queue)).suiv=nouveau; } else printf("espace insufaisantn") } Procedure Empiler(var F:File, int x) Var nouveau:File Debut allouer(nouveau) si (nouveau!=Nil) alors *nouveau.val<-x *nouveau.suiv<- NIL si(F.queue==Nil) alors F.tete<-nouveau F.queue<-nouveau sinon *(F.queue).suiv<- nouveau finsi sinon écrire("espace insufaisantn") Fin
  • 77. Activité 15 46 ASD II Dr.Fadoua Bouafif  Ecrire un sous programme qui permet de supprimer un élément de la File En C En algorithmique int defiler(File *F) { int x; Nœud *elt; if ((*F).queue==NULL) printf("la file est vide"); else { elt=(*F).tete; x=(*elt).val; (*F).tete=(*(*F).tete).suiv; free(elt); } } fonction defiler(var F:File):entier Var x:entier elt:↑ Nœud Debut si (F.queue==Nil) alors ecrire (“la file est vide”) sinon elt<-F.tete x<- (*elt).val F.tete<-*(F.tete).suiv Liberer(elt) finsi Fin
  • 78. Conclusion 54 ▶ Un tableau permet de représenter efficacement un ensemble de valeurs, dont la taille est fixée à l’avance. ▶ Les problèmes d’allocation de mémoire relative à la structure tableau (espace insuffisant ou superflu) sont résolus à travers l’utilisation de la structure dynamique, liste chainée. ▶ Les opérations d’insertion et de suppression d’un élément sont plus faciles à implanter avec la structure liste, par rapport à la structure tableau. ASD II Dr.Fadoua Bouafif
  • 79. Conclusion 55 ▶ Les piles et les files sont des cas particuliers de listes chainées (linéaires) ▶ Ces deux structures s’adaptent à certaines situations: ▶ Les piles sont le moyen le plus efficace pour exécuter les fonctions récursives ▶ Les files sont utilisées surtout dans les opérateurs d’E/S des périphériques de l’ordinateur, ainsi que la gestion des problèmes de file d’attente ▶ Le choix de l’implémentation des piles ou des files dépend du cas qui se présente. Si le volume d’information n’est pas important, l’implémentation contigüe est utile. Dans le cas contraire, l’emploi des pointeurs est plus efficace pour économiser de l’espace mémoire ASD II Dr.Fadoua Bouafif