Académique Documents
Professionnel Documents
Culture Documents
La « liste chaînée » est une structure de données linéaire à accès indirect qui n'a pas de
dimension fixée à sa création. Ses éléments de même type sont éparpillés dans la mémoire et
reliés entre eux par des pointeurs. Sa dimension peut être modifiée selon la place disponible
en mémoire. La liste est accessible uniquement par sa tête de liste c’est-à-dire son premier
élément. Pour ajouter, supprimer ou déplacer un élément il suffit d'allouer une place en
mémoire et de mettre à jour les pointeurs des éléments.
Une liste simplement chaînée est une suite d’un nombre variable de cellules (enregistrements)
de même type liées entre elles par des pointeurs: chaque cellule, sauf la dernière, pointe vers
son successeur. Il suffit de connaître le pointeur du début de la liste (tête) pour accéder aux
différents autres éléments de la liste.
Chaque cellule (enregistrement) contient 2 champs :
• L’information utile.
• Un pointeur qui pointera vers la cellule (enregistrement) suivante.
Il faut conserver une "trace" du premier enregistrement afin de pouvoir accéder aux autres :
1 / 20
Chap4_ASD2 FST LCS1
La structure de donnée qui permet de représenter une liste simplement chaînée dans le cas
général est déclarée comme suit :
Type
Cellule = enregistrement
valeur : type
FinEnregistrement
Liste : ^Cellule
Var
Le type Cellule qui est un enregistrement formé de deux champs : un qui contient la valeur de
l’élément donc le type peut être un type quelconque et le 2ème champ (suivant) contient un
pointeur vers la cellule suivante. C'est-à-dire il contient l’adresse de la cellule suivante. La
dernière cellule ne pointe vers rien donc elle doit contenir la valeur Nil.
Le type Liste est un pointeur sur Cellule qui contient l’adresse du 1er élément de la liste.
Exemple :
Pour simplifier on va travailler sur une liste dont le champ « valeur » est de type entier. Alors
la définition du type liste sera comme suit :
Type
Cellule = enregistrement
valeur : entier
suivant : ^Cellule
FinEnregistrement
Liste : ^Cellule
Var
Tête :Liste
La première procédure de base qu’on doit écrire pour pouvoir manipuler des données de type
liste est la procédure Init( ) qui prend en entrée une liste Tête et l’initialise en liste vide.
Début
Tête NIL
Fin
3 / 20
Chap4_ASD2 FST LCS1
La fonction ListeVide ( ) qui prend en entrée une liste et retourne vrai si elle est vide et faux
sinon.
Début
ListeVide ← Vrai
Sinon
ListeVide ← Faux
FinSi
Fin
La fonction PosFin ( ) prend en entrée une liste et retourne un pointeur vers le dernier élément
de la liste.
Var
P : Liste
Début
P← Tête
P←P^.suivant
Fintanque
FinSi
PosFin←P
Fin
4 / 20
Chap4_ASD2 FST LCS1
La procédure AjouterTête ( ) prend en entrée une valeur à ajouter en tête d’une liste donnée.
Cette procédure doit créer une nouvelle variable dynamique pour contenir la nouvelle cellule,
puis remplir le champ valeur et le champ suivant de cette cellule ensuite mettre l’adresse de
cette cellule dans le pointeur pointant sur la tête de liste (Tête).
Var
NouvCell : Liste
Début
Allouer (NouvCell)
NouvCell ^.valeur ← x
Tête← NouvCell
5 / 20
Chap4_ASD2 FST LCS1
Sinon
Tête← NouvCell
FinSi
Fin
Ajouter un élément à la fin d’une liste
La procédure AjouterFin() prend en entrée une valeur à ajouter à la fin d’une liste donnée ;
Procédure AjoutFin(VAR Tête : Liste, x :entier) Procédure AjoutFin_V2(VAR Tête : Liste, x :entier)
Var Var
NouvCell, P : Liste NouvCell, P : Liste
Début Début
Allouer (NouvCell) Allouer (NouvCell)
NouvCell^.valeur← x NouvCell^.valeur←x
NouvCell ˆ.suivant← NIL NouvCell ˆ.suivant←NIL
Si ListeVide(Tête) Alors //cas où la liste est Si ListeVide(Tête) Alors //cas où la liste est
vide vide
Tête ← NouvCell Tête ← NouvCell
Sinon //cas où la liste n’est pas vide Sinon //cas où la liste n’est pas vide
P ← Tête P ←PosFin(Tête)
Tantque(Pˆ.suivant< >NIL) faire Pˆ.suivant← NouvCell
P ← Pˆ.suivant FinSi
Fintanque
Fin
Pˆ.suivant← NouvCell
FinSi
Fin
Cette procédure permet l’insertion d’une nouvelle cellule après une position donnée en
paramètre sachant que cette cellule n’est pas la dernière dans la liste.
6 / 20
Chap4_ASD2 FST LCS1
Cette fonction permet de rechercher un élément dans une liste. Elle renvoie la position de
l’élément x s’il existe et NIL s’il n’existe pas.
Fintantque Fin
rechercher← P
Fin
7 / 20
Chap4_ASD2 FST LCS1
VAR
P : Liste
DEBUT
P ← Tête
Tête ←Tête^.suivant
LIBERER (P)
P ← NIL
FinSi
FIN
VAR
P : Liste
Début
LIBERER (Tête)
Tête ← NIL
Sinon
8 / 20
Chap4_ASD2 FST LCS1
P ← Tête
P ← P^. suivant
LIBERER (P^.suivant)
Fin Si
Fin Si
FIN
9 / 20
Chap4_ASD2 FST LCS1
Dans les listes vues précédemment le parcours ne peut se faire que dans un seul sens : de la
tête vers la queue. Pour remédier à cette dissymétrie de l’opération et permettre un parcours
aussi bien dans un sens que dans l’autre, on peut construire des listes doublement chaînées (ou
listes bilatères ou listes bidirectionnelles)
II- Définition
Une liste doublement chaînée comporte deux pointeurs qu’on appelle « précédent» et
«suivant ». Si un élément a un prédécesseur, il est désigné par le pointeur « précédent », s’il a
un successeur, il est désigné par le pointeur « suivant ». Cette structure permet de parcourir la
liste dans les 2 sens et d’accélérer la recherche d’un élément.
10 / 20
Chap4_ASD2 FST LCS1
TYPE
Cellule = enregistrement
précédent : ^Cellule
valeur : entier
suivant : ^Cellule
Fin enregistrement
ListeDC = ^Cellule
VAR
Tête,Queue : ListeDC
P^.valeur ←x
P^.précédent ←NIL
Si (Tête = NIL) Alors //Liste vide
P^.suivant ← NIL
Tête← P
11 / 20
Chap4_ASD2 FST LCS1
Queue←P
Sinon //Liste n’est pas vide
P^.suivant ← Tête
Tête^.précédent ← P
Tête ← P
Fin si
Fin
Queue^.suivant P
P^.précédent Queue
Queue P
Fin Si
Fin
12 / 20
Chap4_ASD2 FST LCS1
Var
P: ListeDC
Début
Allouer (P)
P^.valeur ← x
P^.suivant ← position^.suivant
P^.précédent ← position
(position^.suivant)^.précédent ← P
position^.suivant ← P
Fin
La fonction recherche permet de vérifier si l’élément x existe dans la liste. Elle renvoie la
position de l’élément x s’il existe et NIL s’il n’existe pas.
13 / 20
Chap4_ASD2 FST LCS1
Queue ← NIL
Sinon Si position = Tête Alors // Supprimer l’élément en tête
Tête ← Tête^.suivant
Tête^.précédent ← NIL
Liberer(position)
position ← NIL
Sinon Si position = Queue Alors // Supprimer le dernier élément
(Queue^.précédent)^.suivant ← NIL
Queue ←Queue^.précédent
Liberer (position)
position ← NIL
Sinon // l’élément à supprimer est au milieu
(position^.précédent)^.suivant ← position^.suivant
(position^. suivant) ^. précédent ← position^. précédent
Libérer (position)
position ← NIL
FinSi
Sinon
Ecrire (« L’élément à supprimer n’existe pas »)
FinSi
Fin
14 / 20
Chap4_ASD2 FST LCS1
Il est possible d’afficher les éléments de la liste doublement chaînée du dernier élément
vers le premier. Le pointeur de parcours, P, est initialisé avec l'adresse contenue dans
« Queue ». Il prend les valeurs successives des pointeurs « précédent » de chaque élément de
la liste. Le parcours s'arrête lorsque le pointeur de parcours a la valeur Nil.
Puis l'exemple d'une liste doublement chaînée circulaire. : Le dernier élément pointe sur le
premier, et le premier élément pointe sur le dernier.
15 / 20
Chap4_ASD2 FST LCS1
II- Déclaration
La cellule est la même que pour une liste chaînée simple ou double non circulaire. Le
parcours se fait à partir de n'importe quelle adresse de maillon (cellule) contenue dans le
pointeur « Courant » jusqu'à retrouver cette même adresse.
III- Manipulation des listes simplement chaînées circulaires
1. Initialisation
Procédure Init(VAR Courant : Liste)
Début
Courant NIL
Fin
Allouer (NouvCell)
NouvCell ^.valeur ← x
Courant^.suivant ← NouvCell
FinSi
Fin
16 / 20
Chap4_ASD2 FST LCS1
3. Suppression
De même que pour ajouter, pour supprimer un élément, il nous faut le pointeur courant.
L’élément à supprimer se trouve après l'élément courant.
Pour supprimer un élément dans la liste, tout d'abord, il faut vérifier que la liste n'est pas
vide et puis il faut considérer ces situations :
Var
AS : Liste
Début
Libérer(Courant)
Courant NIL
Sinon
AS Courant ^.suivant
Courant^.suivant AS^.suivant
Libérer(AS)
AS NIL
FinSi
FinSi
Fin
4. Affichage
Si la liste n'est pas vide, pour parcourir et afficher la liste à partir du maillon « Courant »,
nous avons besoin de conserver l'adresse contenue dans ce maillon courant afin de pouvoir la
reconnaître et savoir que le parcours est terminé. Nous n'utilisons pas le pointeur « Courant »
pour ce parcours mais un autre pointeur « P » qui prend la valeur de « Courant » au départ. La
17 / 20
Chap4_ASD2 FST LCS1
valeur de « Courant » ne bouge donc pas. On s’arrête lorsque la fin de la liste est arrivée, c'est
à dire si P= Courant.
Allouer (NouvCell)
NouvCell ^.valeur ← x
18 / 20
Chap4_ASD2 FST LCS1
(NouvCell^.suivant)^.précédent ← NouvCell
FinSi
Fin
3. Suppression
Pour supprimer il nous faut le pointeur courant. L’élément à supprimer se trouve après
l'élément courant.
Var
AS : ListeDC
Début
Libérer(Courant)
Courant NIL
Sinon
AS Courant ^.suivant
Courant^.suivant AS^.suivant
(AS^.suivant)^.précédent Courant
Libérer(AS)
AS NIL
FinSi
FinSi
19 / 20
Chap4_ASD2 FST LCS1
Fin
4. Affichage
20 / 20