Vous êtes sur la page 1sur 6

Les listes chaînées

I. Introduction
Jusqu'à maintenant, pour mémorise une liste des données qui concerne des étudiants ou des
employés, nous avons utilisé les tableaux. Ces derniers sont des structures statiques dont la taille, fixée
dès le début, ne varie pas. D'autre part, au niveau mémoire, si on déclare un tableau de 20 entiers, le
compilateur doit trouver une vingtaine de cases mémoires successives de taille un entier (les cases en
bleu dans la figure a).

-a- -b-

Figure 1. Structure de la mémoire vive d'un ordinateur

Les listes chainées sont des structures composées des cellules. Chaque cellule contient deux champs (ou
trois selon le type de la liste) le premier contient la variable et le deuxième un pointeur vers la cellule
qui suit. De cette façon, on peut enregistrer les cellules dans n'importe quelle case mémoire entier (les
cases en bleu dans la figure b). Néanmoins, il faut garder l'adresse de la tête de la liste, et puisque chaque
cellule a un lien vers son successeur (l'adresse de la cellule qui suit), on peut trouver tout le reste de la
liste. Avec les listes chainées, le compilateur n'est pas obligé de trouver des cases successives vides dans
la mémoire. Ces cases peuvent êtres éparpillés dans toute la mémoire ce qui constitue un gain
considérable.

II. Liste simplement chainée


Les listes chainées sont formées par une ou plusieurs cellules. Chacune de ces cellules est formée
en plus de l'élément information, un deuxième champ qui contient l'adresse de la cellule successive. Le
premier champ peut être de différents types, soit simple (entier, réel, caractères ou chaînes de caractères)
soit composé (structure de donnée).
Il est précédemment indiqué, qu'il suffit d'avoir l'adresse de la première cellule pour atteindre
pas à pas la dernière. Donc la liste chaînée est accessible par l'adresse de la tête. La fin de la liste est
indiquée par une adresse de valeur NULL appelée aussi nil (voir la figure 2).
Tête

@ c E1 @c2 E2 @c3 E3 null Null

Figure 2. Structure d’une liste chaînée

En supposant que les éléments de la liste sont des entiers, celle-ci se déclare de la façon suivante :

En langage C
typedef struct cellule
{
int elem ;
struct cellule *suiv ;
} cellule ;

cellule *L ;

1. Création d’une liste chaînée


La procédure suivante permet de créer une liste chaînée de n éléments de type entier. En paramètre
entrée-sortie, on a L une variable de type pointeur sur une cellule. Ce pointeur contiendra l'adresse de la
première cellule de laquelle on accèdera à la liste.

void Creation_liste (cellule **L, int n)


{
cellule *p ;
int i ;
*L = NULL ;
for (i=1 ; i<=n ; i++)
En langage C
{ p = (cellule*) malloc (sizeof (cellule)) ;
printf ("Donner un élément ") ;
scanf ("%d", &p→elem) ;
p→suiv = *L ;
*L = p ;
}
}

Remarques :

Il est très important lors de la création d’une liste chaînée, de penser à initialiser la tête de la liste à
null, sinon la liste n’aura jamais de fin et son parcours sera impossible.

Il faut noter qu’en langage C, le paramètre L dans l’entête de la procédure (qui contient la tête de la
liste à modifier) est précédé par deux symboles ‘*’ : *L pour indiquer qu’il s’agit d’un pointeur, et
**L pour indiquer que le paramètre *L est passé par adresse, ce qui est représenté par le mot clé
« Var » dans la version algorithmique. Ainsi, à l’intérieur de toute la procédure, il faut utiliser *L à
chaque fois où l’on veut mentionner ce paramètre.

2. Parcours d’une liste chaînée


a. Parcours itératifs d'une liste chainée

void Affiche_liste_Iter (cellule *L)


{
cellule *p ;

En langage C p=L;
while (p !=NULL)
{
printf (p→elem) ;
p = p→suiv ;
}
}

b. Parcours récursif d'une liste chainée

void Affiche_liste_Rec (cellule *L)


{
if (L !=NULL)
En langage C {
printf (p→elem) ;
Affiche_liste_Rec (L→suiv) ;
}
}

3. Longueur d'une liste chaînée


La fonction récursive suivante permet de calculer le nombre des cellules d'une liste chaînée

int Longueur (cellule *L)


{
En langage C if (L==NULL)
return 0 ;
else
return (1+ Longueur( (L→suiv)) ;
}
4. Insertion d’un élément dans une liste
a. Insertion en tête de liste

Tête

@c E1 @c2 E2 @c3 E3 null Null

a – Etat initial

Tête

@ c E1 @c2 E2 @c3 E3 null Null

E0 @c1
b- Etat final

Figure 3. Principe d’insertion d’un élément en tête de liste

On suppose que la liste initiale contient au moins une cellule.

void Insert_Tete (cellule **L)


{
cellule *p ;
p = (cellule*) malloc (sizeof (cellule)) ;
En langage C
printf ("Donner un élément ") ;
scanf ("%d", &p→elem) ;
p→suiv = *L ;
*L = p ;
}

5. Recherche d’un élément dans une liste chaînée

Les deux fonctions suivantes récursive et itérative permettent de chercher un élément x dans la liste,
elles retournent vrai si x appartient à la liste et faux si on atteint la fin de la liste sans trouver la variable
x.

A. Version itérative

En langage C boolean recherche (cellule *L, int x)


{
cellule *p ;
boolean trouve=false ;
p=L;
while (p !=NULL && trouve==false)
{
if (p→elem==x) Alors
trouve = true ;
p = p→suiv ;
}
return (trouve) ;
}

B. Version récursive

boolean rechercheRec (cellule *L, int x)


{
if (L==NULL)
return false ;
En langage C else
if (L→elem==x)
return true ;
else
return (rechercheRec (L→suiv, x)) ;
}
}

6. Suppression d’un élément d'une liste chaînée


a. Supprimer le premier élément d'une liste

La procédure suivante permet de supprimer la cellule Tête d'une liste chaînée.

Tête

@c E1 @c2 E2 @c3 E3 null Null

a – Etat initial

Tête

@ c E1 @c2 E2 @c3 E3 null Null


b – Etat final

Figure 4. Principe de suppression d’un élément au début de la liste

void supprimerDeb (cellule **L)


{
En langage C cellule *p ;
p = *L ;
*L = *L→suiv;
free(p) ;
}

Vous aimerez peut-être aussi