SlideShare une entreprise Scribd logo
CHAPITRE 7 : LES LISTES CHAINÉES
1. LES LISTES CHAINÉES SIMPLES
2. LES LISTES CIRCULAIRES
3. LES LISTES DOUBLEMENT CHAINÉES
2023-2024
C
1
2023-2024
C Tableau unidimentionnel Introduction
2
Les listes chainées simples
Introduction
 Les tableaux:
 Stocker un ensemble de données de même type d’une façon linéaire
 Taille connue et fixe des éléments
 Insertion et suppression non pratiques qui nécessitent un décalage souvent coûteuses
 Allocation d’un seul bloc en mémoire avec des cases contiguës
 Les listes
 Taille inconnue au départ, elle varie au cours du temps
 Insertion et suppression dynamiques pratiques
 Allocation indépendante de chaque élément, sous la forme d'un maillon (cellule).
Les éléments sont habituellement éparpillés en mémoire.
2023-2024
C Tableau unidimentionnel Introduction
3
Les listes chainées simples
Structures de données récursives
 Rappel sur la récursivité
 Une fonction récursive est une fonction qui appelle lui-même.
 Exemple : définition récursive de la factorielle
 U0 =1
 Un =n * Un-1
 Mise en œuvre
2023-2024
C Tableau unidimentionnel Introduction
4
Les listes chainées simples
Structures de données récursives
 Structure de données récursive
 Une structure de données qui se référence elle-même.
 Exemple : définition récursive d’une liste
 Une liste est :
 Soit vide
 Soit une valeur suivie d’une autre liste
 Elle peut s’écrire :
 Liste ::={} | {valeur, Liste}
 Cette définition s’appuie donc récursivement sur elle-même
 Illustration
2023-2024
C Tableau unidimentionnel Introduction
5
Les listes chainées simples
Introduction
 C’est une façon d'organiser les données en mémoire de manière beaucoup plus
flexible que les tableaux.
 À créer nous-mêmes, comme le langage C ne propose pas ce système de
stockage
 Une liste chaînée est un moyen d'organiser une série de données en mémoire.
Cela consiste à assembler des structures en les liant entre elles à l'aide de
pointeurs.
 On pourrait les représenter comme ceci :
2023-2024
C Tableau unidimentionnel Introduction
6
Les listes chainées simples
Principe
 Chaque élément peut contenir ce que l'on veut : un ou plusieurs int, double,
structures,…
 chaque élément possède un pointeur vers l'élément suivant.
2023-2024
C Tableau unidimentionnel Introduction
7
Les listes chainées simples
Principe
 Contrairement aux tableaux, les éléments d'une liste chaînée ne
sont pas placés côte à côte dans la mémoire.
 Chaque case pointe vers une autre case en mémoire qui n'est pas
nécessairement stockée juste à côté.
2023-2024
C Tableau unidimentionnel Introduction
8
Les listes chainées simples
Principe
 Voilà deux schémas pour expliquer comment se passent l'ajout et la suppression
d'un élément d'une liste chaînée.
 Remarquez : le symbole en bout de chaîne qui signifie que l'adresse de l'élément
suivant ne pointe sur rien, c'est-à-dire sur NULL.
2023-2024
C Tableau unidimentionnel Introduction
9
Les listes chainées simples
Implémentation
 Objectif : Créer une structure qui fonctionne sur le principe que nous venons de
découvrir.
typedef struct Element Element;
struct Element
{
int nombre;
Element* suivant;
};
Un pointeur vers un élément du même type appelé suivant. C'est ce qui permet de lier les
éléments les uns aux autres : chaque élément « sait » où se trouve l'élément suivant en
mémoire.
2023-2024
C Tableau unidimentionnel Introduction
10
Les listes chainées simples
Implémentation
 En plus de la structure qu'on vient de créer (que l'on dupliquera autant de fois
qu'il y a d'éléments), nous allons avoir besoin d'une autre structure pour
contrôler l'ensemble de la liste chaînée.
 Nous créons des variables de type Liste autant qu’on veut de listes chaînées.
 Le pointeur premier de chaque Liste pointe toujours sur le 1er
élément de la liste
 Notre nouvelle structure de contrôle s’appelle Liste et contient seulement un
pointeur qui pointe toujours sur le premier élément de cette liste
typedef struct Liste Liste;
struct Liste
{
Element* premier;
};
2023-2024
C Tableau unidimentionnel Introduction
11
Les listes chainées simples
Implémentation
 En effet, il faut conserver l'adresse du premier élément pour savoir où
commence la liste.
 Si on connaît le premier élément, on peut retrouver tous les autres en « sautant »
d'élément en élément à l'aide des pointeurs « suivant ».
typedef struct Liste Liste;
struct Liste
{ Element* premier;
};
2023-2024
C Tableau unidimentionnel Introduction
12
Les listes chainées simples
Implémentation
 Dernier élément de la liste : Comment le reconnaitre?
 Il suffit de faire pointer le dernier élément de la liste vers NULL, c'est-à-dire de
mettre son pointeur suivant à NULL. Cela nous permet de réaliser un schéma
enfin complet de notre structure de liste chaînée
List
e
Element 1 Element
2
Element
3
Tête Queue
2023-2024
C Tableau unidimentionnel Introduction
13
Les listes chainées simples
Opérations sur listes chainées
 Parmi les fonctions usuelles pour les listes chaînées :
 initialiser la liste ;
 ajouter un élément ;
 supprimer un élément ;
 afficher le contenu de la liste ;
 supprimer la liste entière.
 Vérifier si la liste est vide
 On pourrait créer d'autres fonctions (par exemple pour calculer la taille de la liste)
mais elles sont moins indispensables.
2023-2024
C Tableau unidimentionnel Introduction
14
Les listes chainées simples
Opérations sur listes chainées : Initialisation
 La fonction d'initialisation est la toute première que l'on doit appeler pour créer
la structure de contrôle Liste
Liste * initialiser ()
{
//allocation de l’espace nécessaire pour un pointeur sur Liste
Liste * p=(Liste *)malloc(sizeof(Liste *));
//Si l’allocation n’est pas réussie
if (p == NULL) exit(EXIT_FAILURE);
//Pointer la tête de liste sur NULL
p-> premier = NULL;
return p;
}
2023-2024
C Tableau unidimentionnel Introduction
15
Les listes chainées simples
Opérations sur listes chainées : Initialisation
 La fonction d'initialisation est la toute première que l'on doit appeler pour créer
la structure de contrôle Liste
Liste * initialiser ()
{
//allocation de l’espace nécessaire pour un pointeur sur Liste
Liste * p=(Liste *)malloc(sizeof(Liste *));
//Si l’allocation n’est pas réussie
if (p== NULL) exit(EXIT_FAILURE);
//Pointer la tête de liste sur NULL
p -> premier = NULL;
return p;
}
le type de données est Liste
et p pointe sur la liste créée.
La taille à allouer est
calculée
automatiquement avec
sizeof(*Liste)
En cas d'erreur d’allocation,
on arrête immédiatement
le programme en faisant
appel à exit().
2023-2024
C Tableau unidimentionnel Introduction
16
Les listes chainées simples
Opérations sur listes chainées : Initialisation
 Nous avons donc réussi à créer en mémoire une liste dont le pointeur sur la tête
de liste est NULL (liste vide). Ça ressemble à la figure suivante :
Liste * initialiser ()
{
//allocation de l’espace nécessaire pour un
pointeur sur Liste
Liste * p=(Liste *)malloc(sizeof(Liste *));
//Si l’allocation n’est pas réussie
if (p == NULL) exit(EXIT_FAILURE);
//Pointer la tête de liste sur NULL
p -> premier = NULL;
return p;
}
2023-2024
C Tableau unidimentionnel Introduction
17
Les listes chainées simples
Opérations sur listes chainées : Insertion en tête
 On va étudier l’ajout au début, au milieu et à la fin d’une liste dans ce cours
 Pour nous mettre en situation, imaginons un cas semblable à la fig. suivante : la
liste est composée de trois éléments et on souhaite ajouter un nouveau au
début.
2023-2024
C Tableau unidimentionnel Introduction
18
Les listes chainées simples
Opérations sur listes chainées : Insertion en tête
 Dans un premier temps, on alloue l'espace nécessaire au stockage du nouvel
élément et on y place le nouveau nombre nvNombre. Il reste alors une étape
délicate : l'insertion du nouvel élément dans la liste chaînée.
 Pour mettre à jour correctement les pointeurs, nous devons procéder dans cet
ordre précis :
1. faire pointer notre nouvel élément vers son futur successeur, qui est l'actuel
premier élément de la liste ;
2. faire pointer le pointeur premier vers notre nouvel élément.
 On ne peut pas suivre ces étapes dans l'ordre inverse ! En effet, si vous faites
d'abord pointer premier vers notre nouvel élément, vous perdez l'adresse du
premier élément de la liste ! Faites le test, vous comprendrez de suite pourquoi
l'inverse est impossible.
2023-2024
C Tableau unidimentionnel Introduction
19
Les listes chainées simples
Opérations sur listes chainées : Insertion en tête
 Il va falloir adapter le pointeur premier de la liste ainsi que le pointeur suivant de
notre nouvel élément pour « insérer » correctement celui-ci dans la liste.
void insertion_debut(Liste * p, int nvNombre)
{
/* Création du nouvel élément */
Element *nouveau = (Element*)malloc(sizeof(Element*));
if (p == NULL || nouveau == NULL)
{
exit(EXIT_FAILURE);
}
nouveau -> nombre = nvNombre;
/* Insertion de l'élément au début de la liste */
nouveau -> suivant = p -> premier;
/* MAJ de la tête de liste (premier) */
p -> premier = nouveau;
}
2023-2024
C Tableau unidimentionnel Introduction
20
Les listes chainées simples
Opérations sur listes chainées : Insertion à la fin
 Il va falloir parcourir la liste pour arriver à la fin et changer le chaînage
void insertion_fin(Liste * p, int nvNombre)
{
/* Création du nouvel élément */
Element* nouveau = (Element*) malloc(sizeof(Element*));
if (p == NULL || nouveau == NULL) exit(EXIT_FAILURE);
nouveau -> nombre = nvNombre;
nouveau -> suivant = NULL;
/*arriver jusqu’à la fin*/
Element* der = p -> premier;
while(der -> suivant != NULL) der = der -> suivant;
/* Insertion de l'élément à la fin de la liste */
der -> suivant = nouveau;
}
2023-2024
C Tableau unidimentionnel Introduction
21
Les listes chainées simples
Opérations sur listes chainées : Insertion à une position k
 Il va falloir parcourir la liste pour arriver à la position k tant que k<longueur (liste)
 On va écrire d’abord la fonction qui calcule la longueur de la liste
int longueur(Liste * p)
{
/* Création du nouvel élément */
Element* courant = p -> premier;
if (p == NULL) exit(EXIT_FAILURE);
int compteur = 0;
while (courant != NULL)
{ courant = courant -> suivant;
compteur++;
}
return compteur;
}
Pourquoi ne pas
utiliser p pour le
parcours !!
2023-2024
C Tableau unidimentionnel Introduction
22
Les listes chainées simples
Opérations sur listes chainées : Insertion à une position k
 Si k=1, il s’agit d’une insertion au début
 Sinon si k=longueur(liste)+1 alors il s’agit d’une insertion à la fin
 Sinon :
 Si k<1 ou k>longueur(liste)+1 alors k est invalide
 Sinon
 On alloue de l’espace pour le nouvel élément
 Si c’est bon, on crée le nouvel élément en affectant sa valeur
 On fait le parcours de la liste jusqu’à l’élément à la position k
 On doit garder aussi la position de l’élément précédent de l’élément k car on
doit changer son suivant sur le nouvel élément.
 Le suivant du nouveau doit pointer sur l’élément à la position k actuel pour
prendre sa place
2023-2024
C Tableau unidimentionnel Introduction
23
Les listes chainées simples
Opérations sur listes chainées : Insertion à une position k
void insertion_milieu(Liste * p, int nvNombre, int k)
{
Element *p2=p ->premier, *prec;
if (p == NULL ) exit(EXIT_FAILURE);
if ((k > (longueur(p)+1)) || (k <= 0))
printf("nLa position est invaliden");
else{
if (k ==1) insertion_debut(p, nvNombre);
else if (k == longueur (p)+1) insertion_fin(p, nvNombre);
else {
/* Création du nouvel élément */
Element* p1 = malloc(sizeof(Element*));
if(p1) {
p1->nombre = nvNombre;
for (int i=1; i<k; i++)
{ prec = p2;
p2 = p2->suivant; }
/*Réaliser l'insertion*/
prec->suivant = p1;
p1->suivant = p2; } }
} }
2023-2024
C Tableau unidimentionnel Introduction
24
Les listes chainées simples
Opérations sur listes chainées : Suppression du début
 Il est techniquement possible de supprimer un élément précis au milieu de la
liste.
 Ici, nous allons étudier la suppression du premier élément de la liste
void suppression_debut(Liste * p)
{
if (p == NULL) exit(EXIT_FAILURE);
if (p->premier != NULL)
{
Element *aSupprimer = p->premier;
p ->premier = p ->premier ->suivant;
free(aSupprimer);
}
}
Cette fonction est courte mais il faut bien comprendre qu'on
doit faire les choses dans un ordre précis :
1. faire pointer premier vers le second élément ;
2. supprimer le premier élément avec un free.
Si on faisait l'inverse, on perdrait l'adresse du second
élément !
2023-2024
C Tableau unidimentionnel Introduction
25
Les listes chainées simples
Opérations sur listes chainées : Suppression du début
 On commence par vérifier que le pointeur qu'on nous envoie n'est
pas NULL, sinon on ne peut pas travailler. On vérifie ensuite qu'il y a
au moins un élément dans la liste, sinon il n'y a rien à faire.
 Ces vérifications effectuées, on peut sauvegarder l'adresse de
l'élément à supprimer dans un pointeur aSupprimer.
 On adapte ensuite le pointeur premier vers le nouveau premier
élément, qui est actuellement en seconde position de la liste
chaînée.
 Il ne reste plus qu'à supprimer l'élément correspondant à notre
pointeur aSupprimer avec un free.
2023-2024
C Tableau unidimentionnel Introduction
26
Les listes chainées simples
Opérations sur listes chainées : Suppression de la fin
 si la liste n’est pas vide, alors il faut parcourir la liste jusqu’à le dernier élément
 Il faut aussi maintenir l’avant dernier élément car son suivant va pointer sur
NULL
 A la fin, on doit libérer l’espace alloué par l’ancien dernier élément
2023-2024
C Tableau unidimentionnel Introduction
27
Les listes chainées simples
Opérations sur listes chainées : Suppression de la fin
void suppression_fin(Liste* p)
{
Element* courant =p ->premier;
Element* AvDer;
if (p == NULL ) exit(EXIT_FAILURE);
/*arriver jusqu’à la fin*/
while(courant -> suivant != NULL) {
AvDer = courant;
courant = courant -> suivant;
}
/* Suppression de l'élément de la fin de la liste */
AvDer -> suivant = NULL;
free(courant);
}
courant
2023-2024
C Tableau unidimentionnel Introduction
28
Les listes chainées simples
Opérations sur listes chainées : Affichage
 Partir du premier élément et afficher chaque élément un à un en
«sautant » de bloc en bloc.
void afficher(Liste * p)
{
if (p == NULL) exit(EXIT_FAILURE);
Element *courant = p ->premier;
while (courant)
{
printf("%d -> ", courant ->nombre);
courant = courant >suivant;
}
printf("NULLn");
}
2023-2024
C Tableau unidimentionnel Introduction
29
Les listes chainées simples
Opérations sur listes chainées : Vide/Calcul nbr éléments
 Vérifier si la tête pointe sur NULL sinon calculer le nombre
d’éléments en utilisant un pointeur sur Element pour le parcours de
la liste
void vide(Liste * p)
{
int vide =0;
if(longueur(liste)==0)
vide =1;
if (!vide) printf("Liste non vide et contient %d elements",n);
else
printf("Liste vide");
}
2023-2024
C Tableau unidimentionnel Introduction
30
Les listes chainées simples
Programme principal
 On peut tester ces
opérations dans
une fonction main:
int main()
{
Liste * maListe = initialiser();
Liste * l=initialiser();
insertion_debut(l,5);
afficher(l);
insertion_debut(l,12);
afficher(l);
insertion_fin(l,20);
afficher(l);
insertion_milieu(l,13,2);
afficher(l);
suppression_debut(l);
afficher(l);
suppression_fin(l);
afficher(l);
vide(l);
return 0;
}
En résumé
› Les listes chaînées constituent un nouveau moyen de stocker des
données en mémoire. Elles sont plus flexibles que les tableaux car on
peut ajouter et supprimer des « cases » à n'importe quel moment.
› Il n'existe pas en langage C de système de gestion de listes chaînées, il
faut l'écrire nous-mêmes
› Dans une liste chaînée, chaque élément est une structure qui contient
l'adresse de l'élément suivant.
› Il est conseillé de créer une structure de contrôle (du type Liste dans
notre cas) qui retient l'adresse du premier élément.
› Il existe une version améliorée, mais plus complexe, des listes
chaînées appelée « listes doublement chaînées », dans lesquelles
chaque élément possède en plus l'adresse de celui qui le précède.
C
31
CHAPITRE 7 : LES LISTES CHAINÉES
1. LES LISTES CHAINÉES SIMPLES
2. LES LISTES CIRCULAIRES
3. LES LISTES DOUBLEMENT CHAINÉES
2023-2024
C
32
2023-2024
C Tableau unidimentionnel Introduction
33
Les listes simplement chainées circulaires
Définition
 Une liste, où le pointeur NULL du dernier élément est remplacé par
l’adresse du premier élément, est appelée une liste circulaire.
 Une liste circulaire n’a pas de premier et de dernier élément
 Tous les éléments sont accessibles à partir de n’importe quel autre élément
 Si la liste circulaire contient un seul maillon alors son adresse sera la même de
celle de son suivant
CHAPITRE 7 : LES LISTES CHAINÉES
1. LES LISTES CHAINÉES SIMPLES
2. LES LISTES CIRCULAIRES
3. LES LISTES DOUBLEMENT CHAINÉES
2023-2024
C
34

Contenu connexe

PDF
Cours : les listes chainées Prof. KHALIFA MANSOURI
PDF
Présentation sur les iles les files et les listes.pdf
PDF
ch4_les listes.pdf
PDF
Les_listes_simplement_chainees_en_langag.pdf
PPTX
Structure des données complexes . pptx .
PDF
Cours les Listes doublement chainées Prof. KHALIFA MANSOURI
PDF
Structures donneenew
PDF
Structures donnee
Cours : les listes chainées Prof. KHALIFA MANSOURI
Présentation sur les iles les files et les listes.pdf
ch4_les listes.pdf
Les_listes_simplement_chainees_en_langag.pdf
Structure des données complexes . pptx .
Cours les Listes doublement chainées Prof. KHALIFA MANSOURI
Structures donneenew
Structures donnee

Similaire à atelier_de_prog2_v4 _classroom_programmation.ppsx (20)

PDF
Cours_Listes .pdf
PDF
Chapitre 3 structures séquentielles
PPTX
Coursgbx vfdfvsfvssfdgfgqsfezsdwzdqscxwcdsw
PDF
09 visual basic .net - exercice - liste chainee
PDF
Algorithme et Structures de Donees 2-Structures Linéaires&NonLimeaire.pdf
PPTX
Chapitre 2 : Les Listes chainées en Algo et C
PDF
initiationalgorithmiqueprogrammation.pdf
PDF
INF220 - Algo DUT SRC1 - Cours 2
PDF
les-tableaux-langage-c.pdf-Programmation
PDF
Cours Piles et files en utilisant lesl istes chainées Prof. KHALIFA MANSOURI
PDF
Les listes simplement chaînées en langage C
PDF
Structures sequentielles en C/C++
PPSX
Cours listesdiapo
PPSX
Cours listes
PPTX
1_Liste cgghhkkiiiujuyuuuuuuuyyhaînée.pptx
PPT
Les fondamentaux du langage C
PPTX
2_Liste_circjrhcdjjkljjjgjjkkulaire.pptx
PPTX
Algo II: les files cours + exercices corrigés
PDF
Pointeuren c
Cours_Listes .pdf
Chapitre 3 structures séquentielles
Coursgbx vfdfvsfvssfdgfgqsfezsdwzdqscxwcdsw
09 visual basic .net - exercice - liste chainee
Algorithme et Structures de Donees 2-Structures Linéaires&NonLimeaire.pdf
Chapitre 2 : Les Listes chainées en Algo et C
initiationalgorithmiqueprogrammation.pdf
INF220 - Algo DUT SRC1 - Cours 2
les-tableaux-langage-c.pdf-Programmation
Cours Piles et files en utilisant lesl istes chainées Prof. KHALIFA MANSOURI
Les listes simplement chaînées en langage C
Structures sequentielles en C/C++
Cours listesdiapo
Cours listes
1_Liste cgghhkkiiiujuyuuuuuuuyyhaînée.pptx
Les fondamentaux du langage C
2_Liste_circjrhcdjjkljjjgjjkkulaire.pptx
Algo II: les files cours + exercices corrigés
Pointeuren c
Publicité

Dernier (8)

PPTX
la_logistique_longue_et_courte_distance_au_defi_de_la_transition_-_marie-chri...
PPTX
24102022SA communication interpersonelle3 - Copie [Enregistrement automatique...
PDF
REGLEMENT _INTERIEUR REGLEMENT _INTERIEUR SH
PPTX
Arbre des défauts/suite cours lean M.pptx
PDF
1 - M2 API S2IN - GC - Introduction - 010225.pdf
PPTX
Product lunch about tech and ai and network
PDF
REGLEMENT _INTERIEUR REGLEMENT _INTERIEUR REGLEMENT _INTERIEUR
PDF
Courrierx.co Partage 4 Étapes Pour Envoyer Facilement Des Lettres En Ligne
la_logistique_longue_et_courte_distance_au_defi_de_la_transition_-_marie-chri...
24102022SA communication interpersonelle3 - Copie [Enregistrement automatique...
REGLEMENT _INTERIEUR REGLEMENT _INTERIEUR SH
Arbre des défauts/suite cours lean M.pptx
1 - M2 API S2IN - GC - Introduction - 010225.pdf
Product lunch about tech and ai and network
REGLEMENT _INTERIEUR REGLEMENT _INTERIEUR REGLEMENT _INTERIEUR
Courrierx.co Partage 4 Étapes Pour Envoyer Facilement Des Lettres En Ligne
Publicité

atelier_de_prog2_v4 _classroom_programmation.ppsx

  • 1. CHAPITRE 7 : LES LISTES CHAINÉES 1. LES LISTES CHAINÉES SIMPLES 2. LES LISTES CIRCULAIRES 3. LES LISTES DOUBLEMENT CHAINÉES 2023-2024 C 1
  • 2. 2023-2024 C Tableau unidimentionnel Introduction 2 Les listes chainées simples Introduction  Les tableaux:  Stocker un ensemble de données de même type d’une façon linéaire  Taille connue et fixe des éléments  Insertion et suppression non pratiques qui nécessitent un décalage souvent coûteuses  Allocation d’un seul bloc en mémoire avec des cases contiguës  Les listes  Taille inconnue au départ, elle varie au cours du temps  Insertion et suppression dynamiques pratiques  Allocation indépendante de chaque élément, sous la forme d'un maillon (cellule). Les éléments sont habituellement éparpillés en mémoire.
  • 3. 2023-2024 C Tableau unidimentionnel Introduction 3 Les listes chainées simples Structures de données récursives  Rappel sur la récursivité  Une fonction récursive est une fonction qui appelle lui-même.  Exemple : définition récursive de la factorielle  U0 =1  Un =n * Un-1  Mise en œuvre
  • 4. 2023-2024 C Tableau unidimentionnel Introduction 4 Les listes chainées simples Structures de données récursives  Structure de données récursive  Une structure de données qui se référence elle-même.  Exemple : définition récursive d’une liste  Une liste est :  Soit vide  Soit une valeur suivie d’une autre liste  Elle peut s’écrire :  Liste ::={} | {valeur, Liste}  Cette définition s’appuie donc récursivement sur elle-même  Illustration
  • 5. 2023-2024 C Tableau unidimentionnel Introduction 5 Les listes chainées simples Introduction  C’est une façon d'organiser les données en mémoire de manière beaucoup plus flexible que les tableaux.  À créer nous-mêmes, comme le langage C ne propose pas ce système de stockage  Une liste chaînée est un moyen d'organiser une série de données en mémoire. Cela consiste à assembler des structures en les liant entre elles à l'aide de pointeurs.  On pourrait les représenter comme ceci :
  • 6. 2023-2024 C Tableau unidimentionnel Introduction 6 Les listes chainées simples Principe  Chaque élément peut contenir ce que l'on veut : un ou plusieurs int, double, structures,…  chaque élément possède un pointeur vers l'élément suivant.
  • 7. 2023-2024 C Tableau unidimentionnel Introduction 7 Les listes chainées simples Principe  Contrairement aux tableaux, les éléments d'une liste chaînée ne sont pas placés côte à côte dans la mémoire.  Chaque case pointe vers une autre case en mémoire qui n'est pas nécessairement stockée juste à côté.
  • 8. 2023-2024 C Tableau unidimentionnel Introduction 8 Les listes chainées simples Principe  Voilà deux schémas pour expliquer comment se passent l'ajout et la suppression d'un élément d'une liste chaînée.  Remarquez : le symbole en bout de chaîne qui signifie que l'adresse de l'élément suivant ne pointe sur rien, c'est-à-dire sur NULL.
  • 9. 2023-2024 C Tableau unidimentionnel Introduction 9 Les listes chainées simples Implémentation  Objectif : Créer une structure qui fonctionne sur le principe que nous venons de découvrir. typedef struct Element Element; struct Element { int nombre; Element* suivant; }; Un pointeur vers un élément du même type appelé suivant. C'est ce qui permet de lier les éléments les uns aux autres : chaque élément « sait » où se trouve l'élément suivant en mémoire.
  • 10. 2023-2024 C Tableau unidimentionnel Introduction 10 Les listes chainées simples Implémentation  En plus de la structure qu'on vient de créer (que l'on dupliquera autant de fois qu'il y a d'éléments), nous allons avoir besoin d'une autre structure pour contrôler l'ensemble de la liste chaînée.  Nous créons des variables de type Liste autant qu’on veut de listes chaînées.  Le pointeur premier de chaque Liste pointe toujours sur le 1er élément de la liste  Notre nouvelle structure de contrôle s’appelle Liste et contient seulement un pointeur qui pointe toujours sur le premier élément de cette liste typedef struct Liste Liste; struct Liste { Element* premier; };
  • 11. 2023-2024 C Tableau unidimentionnel Introduction 11 Les listes chainées simples Implémentation  En effet, il faut conserver l'adresse du premier élément pour savoir où commence la liste.  Si on connaît le premier élément, on peut retrouver tous les autres en « sautant » d'élément en élément à l'aide des pointeurs « suivant ». typedef struct Liste Liste; struct Liste { Element* premier; };
  • 12. 2023-2024 C Tableau unidimentionnel Introduction 12 Les listes chainées simples Implémentation  Dernier élément de la liste : Comment le reconnaitre?  Il suffit de faire pointer le dernier élément de la liste vers NULL, c'est-à-dire de mettre son pointeur suivant à NULL. Cela nous permet de réaliser un schéma enfin complet de notre structure de liste chaînée List e Element 1 Element 2 Element 3 Tête Queue
  • 13. 2023-2024 C Tableau unidimentionnel Introduction 13 Les listes chainées simples Opérations sur listes chainées  Parmi les fonctions usuelles pour les listes chaînées :  initialiser la liste ;  ajouter un élément ;  supprimer un élément ;  afficher le contenu de la liste ;  supprimer la liste entière.  Vérifier si la liste est vide  On pourrait créer d'autres fonctions (par exemple pour calculer la taille de la liste) mais elles sont moins indispensables.
  • 14. 2023-2024 C Tableau unidimentionnel Introduction 14 Les listes chainées simples Opérations sur listes chainées : Initialisation  La fonction d'initialisation est la toute première que l'on doit appeler pour créer la structure de contrôle Liste Liste * initialiser () { //allocation de l’espace nécessaire pour un pointeur sur Liste Liste * p=(Liste *)malloc(sizeof(Liste *)); //Si l’allocation n’est pas réussie if (p == NULL) exit(EXIT_FAILURE); //Pointer la tête de liste sur NULL p-> premier = NULL; return p; }
  • 15. 2023-2024 C Tableau unidimentionnel Introduction 15 Les listes chainées simples Opérations sur listes chainées : Initialisation  La fonction d'initialisation est la toute première que l'on doit appeler pour créer la structure de contrôle Liste Liste * initialiser () { //allocation de l’espace nécessaire pour un pointeur sur Liste Liste * p=(Liste *)malloc(sizeof(Liste *)); //Si l’allocation n’est pas réussie if (p== NULL) exit(EXIT_FAILURE); //Pointer la tête de liste sur NULL p -> premier = NULL; return p; } le type de données est Liste et p pointe sur la liste créée. La taille à allouer est calculée automatiquement avec sizeof(*Liste) En cas d'erreur d’allocation, on arrête immédiatement le programme en faisant appel à exit().
  • 16. 2023-2024 C Tableau unidimentionnel Introduction 16 Les listes chainées simples Opérations sur listes chainées : Initialisation  Nous avons donc réussi à créer en mémoire une liste dont le pointeur sur la tête de liste est NULL (liste vide). Ça ressemble à la figure suivante : Liste * initialiser () { //allocation de l’espace nécessaire pour un pointeur sur Liste Liste * p=(Liste *)malloc(sizeof(Liste *)); //Si l’allocation n’est pas réussie if (p == NULL) exit(EXIT_FAILURE); //Pointer la tête de liste sur NULL p -> premier = NULL; return p; }
  • 17. 2023-2024 C Tableau unidimentionnel Introduction 17 Les listes chainées simples Opérations sur listes chainées : Insertion en tête  On va étudier l’ajout au début, au milieu et à la fin d’une liste dans ce cours  Pour nous mettre en situation, imaginons un cas semblable à la fig. suivante : la liste est composée de trois éléments et on souhaite ajouter un nouveau au début.
  • 18. 2023-2024 C Tableau unidimentionnel Introduction 18 Les listes chainées simples Opérations sur listes chainées : Insertion en tête  Dans un premier temps, on alloue l'espace nécessaire au stockage du nouvel élément et on y place le nouveau nombre nvNombre. Il reste alors une étape délicate : l'insertion du nouvel élément dans la liste chaînée.  Pour mettre à jour correctement les pointeurs, nous devons procéder dans cet ordre précis : 1. faire pointer notre nouvel élément vers son futur successeur, qui est l'actuel premier élément de la liste ; 2. faire pointer le pointeur premier vers notre nouvel élément.  On ne peut pas suivre ces étapes dans l'ordre inverse ! En effet, si vous faites d'abord pointer premier vers notre nouvel élément, vous perdez l'adresse du premier élément de la liste ! Faites le test, vous comprendrez de suite pourquoi l'inverse est impossible.
  • 19. 2023-2024 C Tableau unidimentionnel Introduction 19 Les listes chainées simples Opérations sur listes chainées : Insertion en tête  Il va falloir adapter le pointeur premier de la liste ainsi que le pointeur suivant de notre nouvel élément pour « insérer » correctement celui-ci dans la liste. void insertion_debut(Liste * p, int nvNombre) { /* Création du nouvel élément */ Element *nouveau = (Element*)malloc(sizeof(Element*)); if (p == NULL || nouveau == NULL) { exit(EXIT_FAILURE); } nouveau -> nombre = nvNombre; /* Insertion de l'élément au début de la liste */ nouveau -> suivant = p -> premier; /* MAJ de la tête de liste (premier) */ p -> premier = nouveau; }
  • 20. 2023-2024 C Tableau unidimentionnel Introduction 20 Les listes chainées simples Opérations sur listes chainées : Insertion à la fin  Il va falloir parcourir la liste pour arriver à la fin et changer le chaînage void insertion_fin(Liste * p, int nvNombre) { /* Création du nouvel élément */ Element* nouveau = (Element*) malloc(sizeof(Element*)); if (p == NULL || nouveau == NULL) exit(EXIT_FAILURE); nouveau -> nombre = nvNombre; nouveau -> suivant = NULL; /*arriver jusqu’à la fin*/ Element* der = p -> premier; while(der -> suivant != NULL) der = der -> suivant; /* Insertion de l'élément à la fin de la liste */ der -> suivant = nouveau; }
  • 21. 2023-2024 C Tableau unidimentionnel Introduction 21 Les listes chainées simples Opérations sur listes chainées : Insertion à une position k  Il va falloir parcourir la liste pour arriver à la position k tant que k<longueur (liste)  On va écrire d’abord la fonction qui calcule la longueur de la liste int longueur(Liste * p) { /* Création du nouvel élément */ Element* courant = p -> premier; if (p == NULL) exit(EXIT_FAILURE); int compteur = 0; while (courant != NULL) { courant = courant -> suivant; compteur++; } return compteur; } Pourquoi ne pas utiliser p pour le parcours !!
  • 22. 2023-2024 C Tableau unidimentionnel Introduction 22 Les listes chainées simples Opérations sur listes chainées : Insertion à une position k  Si k=1, il s’agit d’une insertion au début  Sinon si k=longueur(liste)+1 alors il s’agit d’une insertion à la fin  Sinon :  Si k<1 ou k>longueur(liste)+1 alors k est invalide  Sinon  On alloue de l’espace pour le nouvel élément  Si c’est bon, on crée le nouvel élément en affectant sa valeur  On fait le parcours de la liste jusqu’à l’élément à la position k  On doit garder aussi la position de l’élément précédent de l’élément k car on doit changer son suivant sur le nouvel élément.  Le suivant du nouveau doit pointer sur l’élément à la position k actuel pour prendre sa place
  • 23. 2023-2024 C Tableau unidimentionnel Introduction 23 Les listes chainées simples Opérations sur listes chainées : Insertion à une position k void insertion_milieu(Liste * p, int nvNombre, int k) { Element *p2=p ->premier, *prec; if (p == NULL ) exit(EXIT_FAILURE); if ((k > (longueur(p)+1)) || (k <= 0)) printf("nLa position est invaliden"); else{ if (k ==1) insertion_debut(p, nvNombre); else if (k == longueur (p)+1) insertion_fin(p, nvNombre); else { /* Création du nouvel élément */ Element* p1 = malloc(sizeof(Element*)); if(p1) { p1->nombre = nvNombre; for (int i=1; i<k; i++) { prec = p2; p2 = p2->suivant; } /*Réaliser l'insertion*/ prec->suivant = p1; p1->suivant = p2; } } } }
  • 24. 2023-2024 C Tableau unidimentionnel Introduction 24 Les listes chainées simples Opérations sur listes chainées : Suppression du début  Il est techniquement possible de supprimer un élément précis au milieu de la liste.  Ici, nous allons étudier la suppression du premier élément de la liste void suppression_debut(Liste * p) { if (p == NULL) exit(EXIT_FAILURE); if (p->premier != NULL) { Element *aSupprimer = p->premier; p ->premier = p ->premier ->suivant; free(aSupprimer); } } Cette fonction est courte mais il faut bien comprendre qu'on doit faire les choses dans un ordre précis : 1. faire pointer premier vers le second élément ; 2. supprimer le premier élément avec un free. Si on faisait l'inverse, on perdrait l'adresse du second élément !
  • 25. 2023-2024 C Tableau unidimentionnel Introduction 25 Les listes chainées simples Opérations sur listes chainées : Suppression du début  On commence par vérifier que le pointeur qu'on nous envoie n'est pas NULL, sinon on ne peut pas travailler. On vérifie ensuite qu'il y a au moins un élément dans la liste, sinon il n'y a rien à faire.  Ces vérifications effectuées, on peut sauvegarder l'adresse de l'élément à supprimer dans un pointeur aSupprimer.  On adapte ensuite le pointeur premier vers le nouveau premier élément, qui est actuellement en seconde position de la liste chaînée.  Il ne reste plus qu'à supprimer l'élément correspondant à notre pointeur aSupprimer avec un free.
  • 26. 2023-2024 C Tableau unidimentionnel Introduction 26 Les listes chainées simples Opérations sur listes chainées : Suppression de la fin  si la liste n’est pas vide, alors il faut parcourir la liste jusqu’à le dernier élément  Il faut aussi maintenir l’avant dernier élément car son suivant va pointer sur NULL  A la fin, on doit libérer l’espace alloué par l’ancien dernier élément
  • 27. 2023-2024 C Tableau unidimentionnel Introduction 27 Les listes chainées simples Opérations sur listes chainées : Suppression de la fin void suppression_fin(Liste* p) { Element* courant =p ->premier; Element* AvDer; if (p == NULL ) exit(EXIT_FAILURE); /*arriver jusqu’à la fin*/ while(courant -> suivant != NULL) { AvDer = courant; courant = courant -> suivant; } /* Suppression de l'élément de la fin de la liste */ AvDer -> suivant = NULL; free(courant); } courant
  • 28. 2023-2024 C Tableau unidimentionnel Introduction 28 Les listes chainées simples Opérations sur listes chainées : Affichage  Partir du premier élément et afficher chaque élément un à un en «sautant » de bloc en bloc. void afficher(Liste * p) { if (p == NULL) exit(EXIT_FAILURE); Element *courant = p ->premier; while (courant) { printf("%d -> ", courant ->nombre); courant = courant >suivant; } printf("NULLn"); }
  • 29. 2023-2024 C Tableau unidimentionnel Introduction 29 Les listes chainées simples Opérations sur listes chainées : Vide/Calcul nbr éléments  Vérifier si la tête pointe sur NULL sinon calculer le nombre d’éléments en utilisant un pointeur sur Element pour le parcours de la liste void vide(Liste * p) { int vide =0; if(longueur(liste)==0) vide =1; if (!vide) printf("Liste non vide et contient %d elements",n); else printf("Liste vide"); }
  • 30. 2023-2024 C Tableau unidimentionnel Introduction 30 Les listes chainées simples Programme principal  On peut tester ces opérations dans une fonction main: int main() { Liste * maListe = initialiser(); Liste * l=initialiser(); insertion_debut(l,5); afficher(l); insertion_debut(l,12); afficher(l); insertion_fin(l,20); afficher(l); insertion_milieu(l,13,2); afficher(l); suppression_debut(l); afficher(l); suppression_fin(l); afficher(l); vide(l); return 0; }
  • 31. En résumé › Les listes chaînées constituent un nouveau moyen de stocker des données en mémoire. Elles sont plus flexibles que les tableaux car on peut ajouter et supprimer des « cases » à n'importe quel moment. › Il n'existe pas en langage C de système de gestion de listes chaînées, il faut l'écrire nous-mêmes › Dans une liste chaînée, chaque élément est une structure qui contient l'adresse de l'élément suivant. › Il est conseillé de créer une structure de contrôle (du type Liste dans notre cas) qui retient l'adresse du premier élément. › Il existe une version améliorée, mais plus complexe, des listes chaînées appelée « listes doublement chaînées », dans lesquelles chaque élément possède en plus l'adresse de celui qui le précède. C 31
  • 32. CHAPITRE 7 : LES LISTES CHAINÉES 1. LES LISTES CHAINÉES SIMPLES 2. LES LISTES CIRCULAIRES 3. LES LISTES DOUBLEMENT CHAINÉES 2023-2024 C 32
  • 33. 2023-2024 C Tableau unidimentionnel Introduction 33 Les listes simplement chainées circulaires Définition  Une liste, où le pointeur NULL du dernier élément est remplacé par l’adresse du premier élément, est appelée une liste circulaire.  Une liste circulaire n’a pas de premier et de dernier élément  Tous les éléments sont accessibles à partir de n’importe quel autre élément  Si la liste circulaire contient un seul maillon alors son adresse sera la même de celle de son suivant
  • 34. CHAPITRE 7 : LES LISTES CHAINÉES 1. LES LISTES CHAINÉES SIMPLES 2. LES LISTES CIRCULAIRES 3. LES LISTES DOUBLEMENT CHAINÉES 2023-2024 C 34

Notes de l'éditeur

  • #1: Le pointeur NUL Seule exception: La valeur numérique 0 (zéro) est utilisée pour indiquer qu'un pointeur ne pointe 'nulle part'. int *P; P = 0;
  • #9: 1. Si on veut travailler de manière générique, l'idéal est de faire un pointeur sur void : void*. Cela permet de faire pointer vers n'importe quel type de données.
  • #32: Le pointeur NUL Seule exception: La valeur numérique 0 (zéro) est utilisée pour indiquer qu'un pointeur ne pointe 'nulle part'. int *P; P = 0;
  • #34: Le pointeur NUL Seule exception: La valeur numérique 0 (zéro) est utilisée pour indiquer qu'un pointeur ne pointe 'nulle part'. int *P; P = 0;