Les listes chaînées
Transcription
Les listes chaînées
Les listes chaînées Introduction Une liste chaînée permet de stocker un ensemble de valeur du même type, comme un tableau. Contrairement au tableau, la taille de la liste chaînée peut varier au cours du temps. En effet, contrairement au tableau, la liste n'est pas allouée en une seule fois, mais chaque élément est alloué indépendamment, sous la forme d'un maillon. Notion de maillon L'élément de base d'une liste chaînée s'appelle le maillon. Il est constitué : d’un champ de données et d'un pointeur vers un maillon. Données pointeur Figure 1.1-Structure d’un maillon dans une liste chaînée Le champ pointeur vers un maillon pointe vers le maillon suivant de la liste. S'il n'y a pas de maillon suivant, le pointeur vaut NIL. 16 Les listes chaînées Notion de liste chaînée Dans une liste chaînée, chaque élément pointe, à l'aide d’un pointeur (suivant) vers l'élément suivant dans la liste ; le dernier élément, par définition, n'a pas de suivant, donc son pointeur suivant vaut nil. premier Figure 1.2-une liste chaînée Pour manipuler une liste chaînée, nous manipulons un pointeur sur le premier élément; comme chaque élément « connaît » l'élément suivant, on peut ainsi accéder à tous les éléments de la liste. Notons enfin que si le pointeur premier vaut nil, on considérera naturellement que la liste est vide (elle ne contient aucun élément). Le premier maillon de la liste est appelé tête, le dernier maillon de la liste est appelé queue. 17 Les listes chaînées Implémentation du type liste chaînée Un maillon est composé de deux champs de types hétérogènes, il est implémenté donc en utilisant les enregistrements de la manière suivante : Type maillon = Enregistrment valeur : entier suivant : ^maillon FinEnregistrment ^maillon maillon maillon ………. Par la suite nous définissons le type liste comme étant un maillon. Type liste =maillon Déclaration d’une variable de type liste Une fois le type liste est défini on peut déclarer une variable de type pointeur sur liste de la manière suivante p : ^liste 18 Les listes chaînées Accès aux champs d’un maillon d’une liste Si p est un pointeur sur une variable de type liste, p^ est la variable pointée par p. cette variable est un enregistrement, pour accéder a ses champs on utilise l’opérateur "." p^. Valeur p^. suivant Initialisation d’une liste à Nil Une liste est vide si le pointeur du premier maillon est vaut nil p Nil Insertion d’une valeur en tête d’une liste Ecrire la procédure InserTete qui permet d’insérer une valeur val en tête d’une liste chaînée donnée par l’adresse de son premier élément (premier). Notons qu’après l’insertion la valeur du premier sera changée, donc le passage doit se faire par adresse. 19 Les listes chaînées premier Figure 1.3-la liste avant l’insertion de la valeur val en tête premier val Figure 1.4-la liste après l’insertion de la valeur val en tête Principe 1. Créer un maillon d’adresse p1 contenant la valeur val p1 nouveau(^liste) p1^.valeur val 2. Créer un lien entre le nouveau maillon et la tête de la liste de telle sorte que p soit le suivant de p1 p1^.suivant premier 3. Le maillon p1 devient le premier maillon de liste p premier p1 20 Les listes chaînées Algorithme PROCEDURE InsertTete(var premier : ^liste, val : entier) Variable p1: ^liste Debut p1 nouveau(^liste) p1^.valeur val p1^.suivant premier premier p1 Fin Récupérer l’adresse du dernier élément d’une liste Ecrire la fonction Dernier qui renvoie l’adresse du dernier élément d’une liste donnée par l’adresse de son premier élément (premier). premier Figure 1.5-la liste avant l’insertion Dernier 21 Les listes chaînées Principe Le dernier élément de la liste s’il existe est un maillon qui ne possède pas de suivant. On fait le parcours de liste du premier élément jusqu’à trouver un maillon dont le suivant vaut nil. L’adresse de ce maillon est renvoyée par la fonction. Algorithme Fonction Dernier( var premier : ^liste) : ^liste Debut tantque(premier <>Nil et premier ^.suivant<>Nil) faire premier premier ^.suivant Fintantque Dernier premier Fin 22 Les listes chaînées Insertion d’une valeur en queue d’une liste Ecrire la procédure InsertQueue qui permet d’insérer une valeur val dans une liste chaînée donnée par l’adresse de son premier élément (premier). Notons qu’après l’insertion la valeur du premier peut changer (dans le cas où la liste est vide) donc le passage doit se faire par adresse. premier Figure 1.6-la liste avant l’insertion de la valeur val en queue premier val Figure 1.7-la liste aprés l’insertion de la valeur val en queue 23 Les listes chaînées Principe Deux cas: Si la liste est vide l’insertion en queue est une insertion en tête. si(premier =Nil) alors InsertTete(premier,val) Sinon • Créer un maillon d’adresse p1 contenant la valeur val et dont l’élément suivant est Nil p1 nouveau(^liste) p1^.valeur val p1^.suivant Nil • Récupérer l’adresse du dernier maillon (Der) et p1 devient le suivant de Der Der dernier(premier) Der^.suivant p1 Finsi 24 Les listes chaînées Algorithme PROCEDURE InsertQueue(var premier : ^liste, val : entier) Variable p1,Der: ^liste Debut si(premier=Nil) alors InsertTete(premier,val) Sinon p1 nouveau(^liste) p1^.valeur val p1^.suivant Nil // il sera le dernier Der dernier(premier) Der^.suivant p1 Finsi Fin 25 Les listes chaînées Longueur d’une liste Écrire la fonction LongListe qui permet de renvoyer le nombre d’éléments d’une liste chaînée donnée par l’adresse de son premier élément (premier). La fonction renvoie 0 si la liste est vide. Principe On fait le parcours de la liste du premier élément jusqu’au dernier en incrémentant un compteur de 1 à chaque passage d’un maillon à son suivant. La valeur de ce compteur au départ vaut 0 FONCTION LongListe(var premier : ^liste) : entier Variable l: entier; Début l 0; Tantque(premier <>Nil) faire l l+1; premier premier ^.suivant; fintantque LongListe l; Fin 26 Les listes chaînées Insertion d’une valeur à une position k dan une liste Écrire la procédure Insertk qui permet d’insérer une valeur val à une position k dans une liste chaînée donnée par l’adresse de son premier élément (premier). La valeur val aura le rang k+1 dans la liste après l’insertion. premier Figure 1.8-la liste avant l’insertion de la valeur val à la position k=2 premier val pk Figure 1.9-la liste après l’insertion de la valeur val à la position k=2 27 Les listes chaînées Principe Si (k =0) alors //Si k=0 l’insertion se fait en tête de la liste. InsertTete(premier,val) Sinon Si (k>LongListe(premier)) alors écrire("la position k=" ,k, " n'existe pas car la liste est de taille",LongListe(premier)) Sinon // Récupérer l’adresse du maillon qui se trouve à la position k (pk) . Pour i de 1 à k faire pk pk^.suivant; Finpour // Créer un maillon d’adresse p1 contenant la valeur val et dont l’élément suivant est le suivant de pk p1 nouveau(^liste) p1^.valeur val // Le suivant de p1 est le suivant de pk. P1^.suivant pk^.suivant // Le suivant de pk devient p1. pk^.suivant p1 Finsi Finsi 28 Les listes chaînées Algorithme PROCEDURE Insertk(var premier : ^liste , k: entier,val: entier) Variable p1,pk : ^liste i: entier Début Si (k =0) alors InsertTete(premier,val) Sinon Si (k>LongListe(premier)) alors écrire("la position k=" ,k, " n'existe pas car la liste est de taille",LongListe(premier)) Sinon pk premier Pour i de 1 à k faire pk pk^.suivant; Finpour p1 nouveau(^liste) p1^.valeur val p1^.suivant pk^.suivant pk^.suivant p1 Finsi Finsi 29 Fin Les listes chaînées Suppression du premier maillon d’une liste Écrire la procédure SuppTete qui permet de supprimer le premier maillon d’une liste chaînée donnée par l’adresse de son premier élément (premier). premier p Figure 1.10-la liste avant la suppression du premier élément premier Figure 1.11-la liste après la suppression du premier élément 30 Les listes chaînées Principe //Si la liste est non vide : on sauvegarde premier dans une variable p. . Si (premier ≠ Nil) alors p premier // La valeur de premier prend la valeur de son suivant. premier premier^.suivant // On libère la zone mémoire d’adresse p. liberer(p) Finsi Algorithme PROCEDURE SuppTete(var premier : ^liste) Variable p : ^Liste Debut Si (premier ≠ Nil) alors p premier premier premier ^.suivant liberer(p) Finsi Fin 31 Les listes chaînées Suppression du dernier maillon d’une liste Écrire la procédure SuppQueue qui permet de supprimer le dernier maillon d’une liste chaînée donnée par l’adresse de son premier élément (premier). Notons qu’après la suppression la valeur du premier peut changer (dans le cas où la liste contient un seul élément, LongListe(premier)=1. premier AvDer Figure 1.12-la liste avant la suppression du dernier maillon premier Figure 1.13-la liste après la suppression du dernier maillon 32 Les listes chaînées Principe //Si la liste est non vide Si (premier ≠ Nil) alors //Si la liste contient un seul élément, la suppression se fait en tête de la liste Si (LongListe(premier)=1) alors SuppTete(premier) // Sinon, On récupère l’adresse de l’avant dernier élément (AvDer) Sinon AvDer premier tantque(AvDer ^.suivant^.suivant) faire AvDer AvDer ^.suivant fintantque // On sauvegarde l’adresse du dernier élément dans une variable p. p AvDer ^.suivant // L’élément d’adresse AvDer devient le dernier élément. AvDer ^.suivant Nil // on libère la zone mémoire d’adresse p. liberer(p) Finsi Finsi 33 Les listes chaînées Algorithme PROCEDURE SuppFin( var premier : ^liste) Vaiable AvDer,p : ^liste Debut Si (premier ≠ Nil) alors Si (LongListe(premier)=1) SuppTete(p) Sinon AvDer premier Tantque(AvDer ^.suivant^.suivant)faire AvDer AvDer ^.suivant Fintantque p AvDer ^.suivant AvDer ^.suivant Nil liberer(p) Finsi Finsi Fin 34 Les listes chaînées Suppression de tous les maillons d’une liste Écrire la procédure SuppListe qui permet de supprimer tous les éléments d’une liste chaînée donnée par l’adresse de son premier élément (premier). Notons qu’après la suppression la valeur du premier vaudra nil. Algorithme PROCEDURE SuppFin(var premier: ^liste) Debut Tantque(premier≠Nil)faire SuppTete(premier) fintantque fin 35 Les listes chaînées Les listes doublement chaînée Dans une liste doublement chaînée un maillon est composé de trois champs : • Un champ de données ; • Un pointeur vers un le maillon suivant. • Un pointeur vers un le maillon précédent. Données Précédent Suivant Figure 1.15-Structure d’un maillon dans une liste doublement chaînée Suivant : Le champ pointeur vers un maillon pointe vers le maillon suivant de la liste. S'il n'y a pas de maillon suivant, le pointeur vaut NIL. Précédent : Le champ pointeur vers un maillon pointe vers le maillon précédent de la liste. S'il n'y a pas de maillon précédent, le pointeur vaut NIL. 36 Les listes chaînées Le type liste doublement chaînée Type maillon = Enregistrement Valeur : entier suivant : ^maillon précédent: ^maillon FinEnregistrement // Définition du type listedc type listedc =maillon premier Figure 1.16-Une liste doublement chaînée 37 Les listes chaînées Insertion d’une valeur en tête d’une liste doublement chainée. Écrire la procédure InserTete qui permet d’insérer une valeur v en tête d’une liste doublement chaînée donnée par l’adresse de son premier élément (premier). Notons qu’après l’insertion la valeur du premier sera changée donc le passage doit se faire par adresse. Principe // Créer un maillon d’adresse p1 contenant la valeur v et dont le pointeur précédent est nil (il sera le premier). p1 nouveau(^listedc) p1^.valeur v p1^.précédent Nil // Créer un lien entre le nouveau maillon et la tête de la liste de telle sorte que p soit le suivant de p1 p1^.suivant p // Créer un lien entre la tête de la liste (si elle existe) et le nouveau maillon de telle sorte que p1 soit le précédent de p. Si (p<>nil) alors p^.précèdent p1 Finsi 4)Le maillon p1 devient le premier maillon de liste p 38 p p1 Les listes chaînées Algorithme PROCEDURE InsertTete(var p : ^listedc, v : entier) Variable p1: ^listedc Debut p1 nouveau(^listedc) p1^.valeur v p1^.précédent Nil p1^.suivant p si(p<>nil) alors p^.précédent p1 Finsi p p1 Fin Suppression du premier maillon d’une liste doublement chaînée Écrire la procédure SuppTete qui permet de supprimer le premier maillon d’une liste doublement chaînée donnée par l’adresse de son premier élément (premier). Notons qu’après la suppression la valeur du premier maillon doit changer, donc le passage doit se faire par adresse. 39 Les listes chaînées Principe // Si la liste est non vide : on sauvegarde premier dans une variable P1. . Si(premier ≠ Nil) alors P1 premier // La valeur de premier prend la valeur de son suivant. premier premier^.suivant // La valeur du précédent prend la valeur nil // On libère la zone mémoire d’adresse P1. libérer(P1) Finsi Finsi 40 Les listes chaînées Algorithme PROCEDURE SuppTete (var p : ^listedc) var P1: ^listedc début P1 ← p ; si (p<>nil) alors p ← p^.suivant ; p^.prec ← nil ; libérer(P1) ; fin si fin 41 Les listes chaînées Les listes circulaires Une liste où le pointeur nil du dernier élément est remplacé par l’adresse du premier élément est appelée liste circulaire. Dans une liste circulaire tous les maillons sont accessibles à partir de n’importe quel autre maillon. Une liste circulaire n’a pas de premier et de dernier maillon. Par convention, on peut prendre le pointeur externe de la liste vers le dernier élément et le suivant serait le premier élément de la liste. liste Figure 1.14-Une liste circulaire 42