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