Documente Academic
Documente Profesional
Documente Cultură
Filière: SMA-S4
Version 2015/2016
(Printemps)
Introduction
• Une liste chainée est un ensemble fini
d’éléments enchainés.
• Les éléments d’une chaines s’appellent des
maillons (ou nœud, élément, etc.).
• Chaque maillon est constitué de deux parties:
données et pointeur.
• Le pointeur enchaine un maillon à son suivant.
• Vous pouvez simuler les listes chainées à un
train.
28/03/2016 Langage C 2 / 69
Introduction
• Une liste chainée est une structure de données qui
change durant l’exécution.
– Les maillons successifs sont connectés par des pointeurs.
– Le dernier élément pointe sur NULL.
– Elle peut augmenter ou diminuer en taille lors de
l'exécution d'un programme.
– Elle ne perd pas d'espace mémoire.
Tête
A B C
28/03/2016 Langage C 3 / 69
Introduction
28/03/2016 Langage C 4 / 69
Illustration: Insertion
A B C
Élément à
X insérer
A B C
28/03/2016 Langage C 5 / 69
Illustration: Suppression
Élément à supprimer
A B C
A B C
28/03/2016 Langage C 6 / 69
Introduction
• Insertion:
– Un enregistrement (maillon, noeud, etc.) est créé en
maintenant le nouvel élément.
– Le pointeur suivant du nouvel enregistrement est
configuré pour le lier à l'élément qui le suit dans la
liste.
– Le pointeur suivant de l'élément qui doit précéder
doit être modifié pour pointer vers le nouvel
élément.
• Suppression:
– Le pointeur suivant de l’élément qui précède
immédiatement celui à supprimer est modifié pour
pointer vers le suivant de l’élément supprimé.
28/03/2016 Langage C 7 / 69
Tableaux Vs Listes Chainées
• Les tableaux sont appropriés à:
– Insérer/supprimer un élément à la fin.
– Accéder directement à n’importe quel élément
• Les listes chainées sont appropriées à:
– Insérer un élément.
– Supprimer un élément
– Des applications où l’accès séquentiel est
demandé.
– Des applications où le nombre d’éléments ne
pourra pas être connu exactement au début.
28/03/2016 Langage C 8 / 69
Types de listes
• En fonction de la manière dont chainage est
utilisé pour maintenir l’adjacence, plusieurs
types différents de listes chaînées sont
possibles.
– Listes linéaires
• Celles que nous avons discutées jusqu'à présent.
tête
A B C
28/03/2016 Langage C 9 / 69
Types de listes
– Listes circulaires
• Le pointeur du dernier élément de la liste pointe vers le
premier élément.
tête
A B C
28/03/2016 Langage C 10 / 69
Types de listes
A B C
28/03/2016 Langage C 11 / 69
Opérations basiques
28/03/2016 Langage C 12 / 69
Type abstrait de données
• C’est quoi un type abstrait de données?
– C’est un type de données défini par le programmeur
– Typiquement plus complexe que les types de données
simples comme int, float, etc.
• Pourquoi abstrait?
– Parce que les détails de l’implémentation son cachés
– Quand on fait quelques opérations (comme
insertion), on appelle simplement une fonction.
– Des détails de comment la liste est implémentée ou
comment la fonction insérer() est écrites ne sont plus
nécessaires.
28/03/2016 Langage C 13 / 69
Étude de cas
• Tout noeud est une structure (type abstrait).
• Soit la structure d’un noeud comme suit:
struct stud {
int code;
char nom[25];
int age;
struct stud *suiv;
};
28/03/2016 Langage C 14 / 69
Création d’une liste
Comment débuter?
• Pour commencer, nous devons créer un nœud
(le premier nœud), et de faire tete pointer sur
lui.
tete=(noeud*)malloc(sizeof(noeud));
code
suiv
nom
tete
age
28/03/2016 Langage C 16 / 69
Comment débuter? …
• S'il y a n nombre de nœuds dans la liste
chaînée initiale:
– Allouer n enregistrements, un par un.
– Lire les champs des enregistrements
– Modifier les chainages des noeuds pour que la
chaine soit formée.
tete
A B C
28/03/2016 Langage C 17 / 69
noeud *creer_liste()
{
int k, n;
noeud *p, *tete;
printf ("\n Combien d’elements?");
scanf ("%d", &n);
for (k=0; k<n; k++)
{
if (k == 0) {
tete= (noeud *) malloc(sizeof(noeud));
p = tete;
}
else {
p->suiv= (noeud *) malloc(sizeof(noeud));
p = p->suiv;
}
scanf ("%d %s %d", &p->code, p->nom, &p->age);
}
p->suiv = NULL;
return (tete);
}
28/03/2016 Langage C 18 / 69
Appel dans le main()
28/03/2016 Langage C 19 / 69
Parcourir une liste
Quoi faire?
28/03/2016 Langage C 21 / 69
void afficher(noeud *tete)
{
int count = 1;
noeud *p;
p = tete;
while (p != NULL)
{
printf ("\nNoeud %d: %d %s %d", count,
p->code, p->nom, p->age);
count++;
p = p->suiv;
}
printf ("\n");
}
28/03/2016 Langage C 22 / 69
• Appeler à partir de la fonction main():
noeud *tete;
………
afficher(&tete);
28/03/2016 Langage C 23 / 69
Insérer un noeud dans une liste
Comment?
28/03/2016 Langage C 25 / 69
Continuer…
• Quand un noeud est ajouté au début,
– Seulement un seul pointeur suiv devra être
modifié.
• Tete pointera sur le nouveau noeud.
• Le nouveau noeud pointera sur l’ex premier élément.
• Quand un noeud est ajouté à la fin,
– Deux pointeurs suiv seront modifiés
• Le dernier noeud pointe sur le noeud ajouté
• Le nouveau noeud pointe sur NULL.
• Quand un noeud est ajouté au milieu,
– Deux pointeurs suiv seront modifiés
• Le noeud précédent pointe sur le noeud ajouté
• Le nouveau noeud pointe sur le noeud suivant.
28/03/2016 Langage C 26 / 69
void inserer (noeud **tete)
{
int k = 0, c1;
noeud *p, *q, *new;
p = *tete;
28/03/2016 Langage C 27 / 69
else
{
while ((p != NULL) && (p->code!= c1))
{
q = p;
p = p->suiv;
}
Les pointeurs p et
if (p == NULL) /* à la fin */
q pointent toujours
{
sur des nœuds
q->suiv= new;
consécutifs.
new->suiv= NULL;
}
else if (p->code == c1)
/* au milieu*/
{
q->suiv= new;
new->suiv= p;
}
}
}
28/03/2016 Langage C 28 / 69
• Appeler à partir de la fonction main():
noeud *tete;
………
inserer (&tete);
28/03/2016 Langage C 29 / 69
Supprimer un noeud d’une liste
Quoi faire?
28/03/2016 Langage C 31 / 69
void supprimer(noeud **tete)
{
int c1;
noeud *p, *q;
p = *tete;
if (p->code== c1)
/* Supprimer le 1er élément */
{
*tete= p->suiv;
free (p);
}
28/03/2016 Langage C 32 / 69
else
{
while ((p != NULL) && (p->code!= c1))
{
q = p;
p = p->suiv;
}
28/03/2016 Langage C 33 / 69
Liste FIFO: First In First Out
In Out
B A
C B A
28/03/2016 Langage C 34 / 69
Liste LIFO: Last In First Out
In Out
C B A B C
Appelée aussi
une PILE
28/03/2016 Langage C 35 / 69
Les piles
Opérations à effectuer sur une pile
28/03/2016 Langage C 36 / 69
Pile-suite
28/03/2016 Langage C 37 / 69
Implémentation des Piles
Pile en utilisant des tableaux
EMPILER
top
top
28/03/2016 Langage C 39 / 69
Pile en utilisant des tableaux
DEPILER
top
top
28/03/2016 Langage C 40 / 69
Pile en utilisant liste chainée
EMPILER
top
28/03/2016 Langage C 41 / 69
Pile en utilisant liste chainée
DEPILER
top
28/03/2016 Langage C 42 / 69
Idée
• En utilisant des tableaux, on pourrait:
– Déclarer un tableau d’une taille fixe (qui détermine la taille maximale
de la pile).
– Maintenir une variable qui pointe toujours sur la tête de la pile.
28/03/2016 Langage C 43 / 69
Déclaration
28/03/2016 Langage C 44 / 69
Création de la Pile
28/03/2016 Langage C 45 / 69
Fonction empiler
void empiler(pile *s, int element)
{
if (s->top == (MAXSIZE-1))
{
printf (“\n débordement ”);
exit(-1);
}
else
{
s->top ++;
s->st[s->top] = element;
}
}
Tableau
28/03/2016 Langage C 46 / 69
Fonction empiler
void empiler (pile **top, int element)
{
pile *new;
new = (pile*) malloc(sizeof(pile));
if (new == NULL)
{
printf (“\n Pile est pleine”);
exit(-1);
}
new->val = element;
new->next = *top;
*top = new;
}
Liste chainée
28/03/2016 Langage C 47 / 69
Dépiler un élément de la pile
int depiler(pile *s)
{
if (s->top == -1)
{
printf (“\n Rien a depiler”);
exit(-1);
}
else
{
return (s->st[s->top--]);
}
}
Tableau
28/03/2016 Langage C 48 / 69
int depiler(pile **top)
{
int t; // la valeur dépilée
pile *p;
if (*top == NULL)
{
printf (“\n pile vide”);
exit(-1);
}
else
{
t = (*top)->val;
p = *top;
*top = (*top)->next;
free (p);
return t;
}
}
Liste chainée
28/03/2016 Langage C 49 / 69
Fonction estVide
28/03/2016 Langage C 50 / 69
Fonction estPlein
Liste chainée
Tableau
28/03/2016 Langage C 51 / 69
main():: tableau
#include <stdio.h> empiler(&A,30);
#define MAXSIZE 100 empiler(&B,100);
empiler(&B,5);
struct lifo
{ printf (“%d %d”,
int st[MAXSIZE]; depiler(&A), depiler(&B));
int top; empiler(&A, depiler(&B));
};
typedef struct lifo pile; if (estVide(&B))
printf (“\n B est vide”);
main()
}
{
pile A, B;
creer(&A); creer(&B);
empiler(&A,10);
empiler(&A,20);
28/03/2016 Langage C 52 / 69
main():: liste chainée
#include <stdio.h> empiler(&A,30);
struct lifo empiler(&B,100);
{ empiler(&B,5);
int val; printf (“%d %d”,
struct lifo *next; depiler(&A),
}; depiler(&B));
typedef struct lifo pile;
empiler(&A,depiler(&B));
main()
if (estVide(&B))
{
printf (“\n B est
pile A, B; vide”);
creer(&A); creer(&B); }
empiler(&A,10);
empiler(&A,20);
28/03/2016 Langage C 53 / 69
Les files: First-In-First-Out
Les opérations à effectuer sur une file
28/03/2016 Langage C 54 / 69
Implémentation d’une file par liste
chainée
Idée de base
– Créer une liste chainée à laquelle les éléments
sont ajoutés d’un côté et supprimés de l’autre
côté.
– On aura besoin de deux pointeurs:
• Un pointant sur la tête de la liste (d’où les éléments
seront supprimés)
• Un autre pointant sur la queue de la liste (d’où les queue
éléments seront insérés).
Enfiler
Tête Queue
28/03/2016 Langage C 57 / 69
File: par liste chainée
DEFILER
Tête Queue
28/03/2016 Langage C 58 / 69
Exemple
• Soit une file de valeurs entières
struct noeud{
int val;
struct noeud *suiv; val *suiv
};
typedef struct noeud fifo;
typedef struct {
fifo *tete, *queue; *tete *queue
} file;
28/03/2016 Langage C 59 / 69
creer-estVide
28/03/2016 Langage C 60 / 69
Fonction enfiler
fifo *enfiler (file *q, int n) if(q->queue==NULL)
{ {
fifo *temp; q->queue=temp;
temp= (fifo *)malloc(sizeof(fifo)); q->tete= q->queue;
if (temp==NULL) }
{ else
printf("Erreur d’allocation \n"); {
return NULL; q->queue->suiv=temp;
} q->queue=temp;
temp->val=n; }
temp->suiv=NULL; return(q->queue);
}
28/03/2016 Langage C 61 / 69
Fonction defiler
28/03/2016 Langage C 62 / 69
Implémentation avec Tableau
28/03/2016 Langage C 63 / 69
Implémentation avec Tableau
ENFILER DEFILER
0 N
28/03/2016 Langage C 65 / 69
• Fonction initfile de création
void initfile(file *q)
{
q->queue= q->tete= 0;
q->plein=0; q->vide=1;
}
28/03/2016 Langage C 66 / 69
Fonction enfiler
void enfiler(file *q, ELEMENT ob)
{
if(estPlein(q)) { printf("File est pleine \n"); return; }
q->queue=(q->queue+1)%(MAX_SIZE);
q->f_elem[q->queue]=ob;
if(q->tete==q->queue) q->plein=1;
else q->plein=0;
q->vide=0;
}
28/03/2016 Langage C 67 / 69
Fonction defiler
ELEMENT defiler(file *q)
{
ELEMENT temp;
if(estVide(q)) { printf("File est vide\n"); return(temp); }
q->tete=(q->tete+1)%(MAX_SIZE);
temp=q->f_elem[q->tete];
if(q->queue==q->tete) q->vide=1; else q->vide=0;
q->plein=0;
return(temp);
}
28/03/2016 Langage C 68 / 69
FIN
28/03/2016 Langage C 69 / 69