Listes chaînées
Une liste chaînée (ou liste liée) est une structure de données composées d’une séquence d’éléments de liste.
Chaque enregistrement d’une liste chaînée est souvent appelé élément , nœud ou maillon.
La tête d’une liste est son premier nœud. La queue d’une liste peut se référer soit au reste de la liste après la tête, soit au dernier nœud de la liste.
Le champ de chaque nœud qui contient l’adresse du nœud suivant ou précédent est généralement appelé lien ou pointeur. Le contenu est placé dans un ou plusieurs autres champs appelés données, informations ou valeur.
Liste chaînée
Chaque élément (ou maillon) M de la liste est composé :
- d’un contenu utile
M.val(de n’importe quel type), - d’un pointeur
M.suivpointant vers l’élément suivant de la séquence.

Le dernier élément de la liste possède un pointeur M.suiv vide : ![]()
Une liste chainée L est entièrement définie par son maillon de tête L.tete, c’est à dire l’adresse de son premier maillon.
On peut également lui ajouter un attribut
L.curpour mémoriser l’adresse d’un maillon « courant ».
Interface (primitives)
Il n’existe pas de normalisation pour les primitives de manipulation de liste ; les plus fréquentes sont :
est_vide(L): renvoie vrai si la listeLest vide,taille(L): renvoie le nombre d’éléments de la listeL,get_dernier_maillon(L): renvoie le dernier élément de la liste,get_maillon_indice(L, i): renvoie le maillon d’indicei,ajouter_debut(L, d): ajoute un maillondau début de la listeL,ajouter_fin(L, d): ajoute un maillondà la fin de la listeL,inserer_apres(L, i, M): insert un maillon à l’indicei,supprimer_apres(L, M): supprime le maillon qui suit le maillonM,- …
Insertion d’un maillon
Pour insérer un maillon nM après un maillon M, il faut :
- Faire pointer le pointeur
nM.suivversM.suiv - Faire pointer le pointeur
M.suivversnM

Suppression d’un maillon
Pour supprimer le maillon suivant un maillon M, il faut :
- Faire pointer le pointeur
M.suivversM.suiv.suiv - Détruire (effacer de la mémoire) le maillon
M.suiv

Remarque : dans certains langages disposants d’un dispositif de ramasse-miettes (comme Python par exemple), le simple fait de ne plus être référencé détruit l’objet
Maillon. Dans d’autres langages, il faut explicitement détruire l’objet, et par conséquent, en garder une référence avant l’étape 1.
Implémentation
Python
On peut implémenter un maillon de liste chaînée en Python à l’aide d’une classe Maillon :
class Maillon:
def __init__(self, v = None):
self.val = v
self.suiv = None # Pas de maillon suivant
Son attribut suiv est de type Maillon, ou bien vaut None si le maillon est le dernier de la liste (le maillon de queue).
Et une liste chaînée s’implémente par une classe ListeChainee :
class ListeChainee:
def __init__(self):
self.tete = None # de type Maillon si la liste n'est pas vire
Son attribut tete est de type Maillon, ou bien vaut None si la liste est vide.
On peut alors créer une liste chainée ainsi :
L = ListeC() M1, M2 = Maillon(14), Maillon(8) M1.suiv = M2 L.tete = M1
On implémente la méthode est_vide(L) simplement de cette manière :
def est_vide(self):
return self.tete is None
On peut implémenter un maillon de liste chaînée en Python à l’aide d’un simple tuple :
Ainsi une liste chaînée serait représentée par son maillon de tête, ou vaudrait None pour une liste chaînée vide.
M2 = (8, None) M1 = (14, M2) L = M1
renverser(M): renverse, sur place, la liste chaînée de maillon de têteMconcatener(M1, M2): retourne une nouvelle liste, résultat de la concaténation des listes de maillons de têteM1etM2.
Récursivité
La structure même d’une liste chainée est récursive : chaque maillon d’une liste chainée est le début d’une nouvelle liste chainée.
C, C++
On peut implémenter un maillon de liste chaînée en C à l’aide d’un objet structure Maillon :
struct Maillon {
float val;
Maillon *suiv;
}
Son attribut suiv est de type Maillon.
Remarque :
*suivest de type structureMaillon, tandis quesuivest un pointeur, c’est à dire l’adresse de*suiv.
Et une liste chaînée s’implémente par une structure ListeC :
struct ListeC {
Maillon *tete;
}
Son attribut tete est de type Maillon.
On peut alors créer une liste ainsi :
ListeC L; Maillon M1, M2; M1.suiv = &M2; L.tete = &M1;
Remarque :
&M1signifie « adresse deM1«
Liste doublement chaînée
Chaque élément (ou maillon) M de la liste est composé :
- d’un contenu utile
M.val(de n’importe quel type), - d’un pointeur
M.suivpointant vers l’élément suivant de la séquence, - d’un pointeur
M.precpointant vers l’élément précédent de la séquence.

Le dernier élément de la liste possède un pointeur .suiv vide : ![]()
et le premier un pointeur .prec vide : ![]()
Interface
Il n’existe pas de normalisation pour les primitives de manipulation de liste; les plus fréquentes sont :
est_vide(L): renvoie vrai si la liste est vide,taille(L): renvoie le nombre d’éléments de la liste,get_dernier_maillon(L): renvoie le dernier élément de la liste,get_maillon_indice(L, i): renvoie le maillon d’indicei,ajouter_debut(L, d): ajoute un élémentdau début de la liste,ajouter_fin(L, d): ajoute un élémentdà la fin de la liste,inserer_apres(L, i, M): insert un maillonMà l’indicei,supprimer_apres(L, M): supprime le maillon suivant le maillonM,- …
Remarque : dans les exemples de fonction précédents,
Mest de typeMaillonalors que l’élémentdest de type quelconque. Mais les fonctions pourraient accepter les deux types : si on passe un objet qui n’est pas un maillon, le maillon devrait alors être automatiquement créé.
Implémentation




