Ajouter un titre au milieu d’une playlist
Une liste chaînée est une suite de nœuds où chaque nœud sait où se trouve le suivant. Elle permet d’insérer ou de supprimer un élément sans décaler tous les autres.
Une application de musique garde votre playlist. Vous glissez un titre entre le troisième et le quatrième. Avec un tableau, tous les titres suivants reculeraient d’une case. Ici, deux liens suffisent.
À la fin de cette leçon
Remarque
Je peux construire une liste chaînée et la parcourir.
Mots-clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Nœud | un élément qui garde une valeur et un lien vers le suivant | |
| Tête | le premier nœud de la liste | |
| Liste chaînée | des nœuds reliés les uns aux autres | |
| Parcours | passer de nœud en nœud depuis la tête | |
| Classe | un modèle qui décrit des objets de même forme | class Noeud |
| None | la valeur qui veut dire rien, donc la fin de la liste |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Chaque nœud garde une valeur et un lien
Dans une liste chaînée, les éléments ne sont pas côte à côte en mémoire. Chaque nœud garde sa valeur et un lien vers le nœud suivant.
Le dernier nœud n’a pas de suivant : son lien vaut None. Pour retrouver toute la liste, il suffit de connaître la tête, c’est-à-dire le premier nœud.
Une classe décrit la forme d’un nœud
Pour fabriquer des nœuds en Python, on écrit une classe. C’est un modèle qui décrit des objets de même forme.
La méthode __init__ s’exécute quand on crée un objet. self désigne l’objet en cours de création. Ici, chaque Noeud a deux attributs : valeur et suivant.
Relier trois nœuds et les parcourir
class Noeud:
def __init__(self, valeur):
self.valeur = valeur
self.suivant = None
# Trois nœuds reliés : 10, 20, 30.
a = Noeud(10)
b = Noeud(20)
c = Noeud(30)
a.suivant = b
b.suivant = c
# Parcours : on part de la tête et on suit les liens.
courant = a
while courant is not None:
print(courant.valeur)
courant = courant.suivant
# Ajoutez un nœud 40 à la fin, puis relancez.
En C, un nœud est une structure
En C, un nœud est une structure qui range une valeur et un pointeur, c’est-à-dire l’adresse du nœud suivant. Le programme des commandes suivantes relie trois nœuds, les parcourt, puis affiche la taille d’un nœud.
Un entier prend 4 octets et une adresse 8 octets. Le compilateur arrondit à 16 pour aligner l’adresse. Les deux premières commandes n’affichent rien.
Écrire le programme C
printf '%s\n' '#include <stdio.h>' 'struct noeud { int valeur; struct noeud *suivant; };' 'int main(void) {' ' struct noeud c = {30, NULL};' ' struct noeud b = {20, &c};' ' struct noeud a = {10, &b};' ' for (struct noeud *p = &a; p != NULL; p = p->suivant) printf("%d\n", p->valeur);' ' printf("taille du noeud : %d octets\n", (int)sizeof(struct noeud));' ' return 0;' '}' > /tmp/liste.cAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Compiler avec gcc
gcc -o /tmp/liste /tmp/liste.cAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Parcourir les trois nœuds
/tmp/listeAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Insérer ou supprimer ne décale rien
Pour insérer un nœud après un autre, on change deux liens. Le nouveau nœud reprend le suivant de l’ancien. Puis l’ancien désigne le nouveau.
Pour supprimer, le nœud d’avant saute par-dessus. Rien ne bouge en mémoire. En revanche, atteindre le nœud numéro k oblige à suivre k liens depuis la tête.
Exemple travaillé : insérer 25 entre 20 et 30
| Étape | Action | Liste obtenue |
|---|---|---|
| Départ | Rien encore | 10 → 20 → 30 |
| 1 | Créer le nœud 25 | 25 → rien |
| 2 | Le lien de 25 reçoit le suivant de 20 | 25 → 30 |
| 3 | Le lien de 20 désigne 25 | 10 → 20 → 25 → 30 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Tableau ou liste chaînée : les coûts
| Opération | Tableau | Liste chaînée |
|---|---|---|
| Lire l’élément numéro k | 1 étape | k étapes |
| Insérer en tête | n étapes | 1 étape |
| Insérer après un nœud connu | n étapes | 1 étape |
| Supprimer après un nœud connu | n étapes | 1 étape |
| Chercher une valeur | n étapes | n étapes |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Inverser une liste, c’est retourner chaque lien
Pour inverser une liste, on la parcourt en retournant chaque lien. Il faut trois repères : precedent, courant et suivant.
On garde d’abord le suivant, sinon la fin de la liste est perdue. Puis le lien de courant désigne precedent. Enfin, on avance d’un nœud.
Exemple travaillé : inverser 1, 2, 3
| Tour | courant | precedent | Chaînes obtenues |
|---|---|---|---|
| Départ | 1 | rien | 1 → 2 → 3 |
| Après le tour 1 | 2 | 1 | 1 → rien et 2 → 3 |
| Après le tour 2 | 3 | 2 | 2 → 1 → rien et 3 |
| Après le tour 3 | rien | 3 | 3 → 2 → 1 → rien |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Erreur fréquente
Attention
Beaucoup d’étudiants écrivent courant.suivant = precedent sans avoir gardé le suivant avant. Le lien vers la suite est alors perdu, et tout le reste de la liste disparaît. Écrivez toujours suivant = courant.suivant en premier.
Pour aller plus loin
Écrivez une fonction longueur(tete) qui compte les nœuds. Écrivez ensuite supprimer(tete, valeur), qui retire le premier nœud portant cette valeur.
Pensez au cas où la valeur est dans la tête : la fonction doit alors rendre une autre tête.