Chapitre 2 Liste chainée

publicité
Chapitre 2
Liste chainée
En informatique, une liste chainée est une structure de données qui représente une collection de données ordonnées et de taille arbitraire d'éléments
de même type, l'accès aux éléments d'une liste chainées est séquentielle :
l'accès à un élément permet l'accès à son suivant au contraire de la structure
de données tableau l'accès à l'information se fait de manière absolue avec un
adressage direct aux cellules du tableau. La gure 2.1 montre la représentation graphique de la liste chainées, cette représentation permet une meilleur
compréhension de ses structures. La structure de la liste chaînée en plus de
Chainage
Inf
Valeur NULL
Inf
Inf
Inf
Dernier élément/
donnée
Figure 2.1 Représentation d'une liste chainée
la donnée est que chaque élément possède un /ou plusieurs pointeurs vers les
éléments qui lui sont logiquement adjacents dans la liste. De ce fait, l'usage
d'une liste est préconisé pour des raisons de rapidité de traitement, lorsque
les insertions et suppressions d'élément en tout point sont relativement plus
fréquentes que les accès simples, dans la littérature on trouve l'appellation
Liste Linéaire Chainée (LLC) fréquemment utilisée . En eet, les insertions
1
en début ou n de liste et les suppressions se font en temps constant car
elles ne demandent au maximum que deux accès en écriture. En revanche,
l'accès à un élément aléatoirement positionné nécessite le parcours de chaque
élément qui sépare l'index de l'élément choisi. Il est donc préférable d'avoir
un accès séquentielle aux éléments .
2.1
Pourquoi les listes chainées
Pour savoir la raison d'utiliser les listes, il faut retourner vers les tableaux,
car l'utilisation de tableau montrait que qu'ils était gés et ne permettait
pas de modier sa taille à moins qu'on déclare un autre tableau, de même,
pour ajouter un élément ou de l'insérer au milieu. De ce fait les tableaux
montrent une limite majeure (voir gure 2.2). Les langages de programmation
Le tableau ne permet pas de modifier sa taille
á moins qu’on le redéclare avec une taille differente
Figure 2.2 Limite du tableau
proposent les structures de données dynamiques pour combler le manque
signaler dans les tableaux, cette technique permet d'implémenter les listes par
l'utilisateur selon ses besoins, ainsi on peut ajouter, insérer ou supprimer un
élément sans faire une déclaration. En résumé, il retenir les points suivants :
Pour déclarer un tableau, il faut connaître sa taille.
pour supprimer ou ajouter un élément à un tableau, il faut créer un
nouveau tableau et supprimer l'ancien.
la taille d'une liste chainée est inconnue au départ, elle peut contenir
autant d'éléments que supporte la mémoire.
pour accéder au iieme élément il faut parcourir la liste i − 1 fois.
toutes les opérations sont réalisables sur une liste chainée.
2.2
Implémentation
La structure de données de la liste chainée contient deux parties :
la valeur que vous voulez stocker,
2
l'adresse de l'élément suivant, s'il existe sinon l'adresse sera N U LL, et
désignera le bout de la chaîne.
type l i s t =^p o i n t e u r
v a l u e : i n t e g e r ; ( ∗ ou n ' i m p o r t e q u e l a u t r e type ∗ )
next : l i s t ;
end ;
Listing 2.1 déclaration de type liste chainée
Figure 2.3 Ajout un élément au début de la liste
2.3
Fonctions de gestion de liste
Dans cette section on va présente quelques fonctions de base pour exploiter les listes chainées, sa n'empêche pas qu'ils existent d'autres fonction et
procédures permettant la gestion de ces listes.
Remarque importante :
la liste est connue par l'adresse du premier élément si cette adresse n'est
pas mémorisée la tête de la liste disparait, donc il faut toujours avoir la tête
de la liste mémorisée.
2.3.1 Ajout d'éléments à la liste
Dans cette procédure qui prend comme paramètres value la nouvelle
valeur à insérer et head la liste qui contient les éléments, on peut insérer cette
3
valeur à la liste selon deux choix le premier est d'insérer au début de la liste et
le deuxième l'insertion se fait à la n de liste. Pour le premier choix (comme
le montre la gure 2.3) le nouvel élément est créé par l'instruction new(p) qui
permet d'allouer une cellule de mémoire et ensuite aecté le paramètre valeur
à cette cellule, comme on veut que cette nouvelle cellule soit en premier de
cette liste, on fait le chainage vers la tete par l'instruction p.Suivant := tete
et ensuite la tete :=p, on remarque que tete et p fait référence à la même
adresse.
Procédure
addtof ront( var head : list, value : integer)
p : list Début
new(p);
p ↑ .value ← valeur;
p ↑ .next ← head;
head ← p;
Fin
Algorithme 1 Ajout d'un élément à la tête de la liste
addtoend( var head : list, value : integer)
p, L : list
Procédure
Début
L ← head; new(p);
p ↑ .value ← valeur;
p ↑ .next ← nil;
Si (head = nil ) Alors
head ← p
Sinon
Tant que
(L ↑ .next 6= nil)
L ← L ↑ .next;
faire
Fait
L ↑ .next ← p;
Fin Si
Fin
Algorithme 2 Ajout d'un élément à la n de la liste
4
Figure 2.4 Ajout un élément à n de la liste
2.3.2 Achage d'éléments de la liste
Selon l'algorithme 3 qui est itératif, on ache value jusqu'on arrive à la
n de la liste c'est à dire p=NIL. Une autre version peut être mise en place
d'une façon récursive.
display ( var head : list, value : integer)
p, L : list Début
Si (head = nil ) Alors
ecrire('la liste est vide')
Procédure
Sinon
L ← head;
(L 6= nil) faire
L ← L ↑ .next;
ecrire(L ↑ .value);
Tant que
Fait
Fin Si
Fin
Algorithme 3 Ajout d'un élément à la n de la liste
5
2.3.3 Rechercher dans une liste
On parcoure la liste, si on atteint la n de la liste et l'élément n'existe
pas la fonction retourne faux, sinon elle retourne vrai.
Search( var head : list, value : integer) :
p, L : list;
trouve : booleen; Début
p ← head;
trouve ← f alse;
Tant que ((p 6= nil) and not trouve) faire
Si (value = p ↑ .value) Alors
trouve ← true;
Fonction
booleen
Sinon
p ← p ↑ .next;
Fin Si
Fait
Search = trouve
Fin
Algorithme 4 Recherche d'un élément dans la liste
2.3.4 Suppression d'un élément ou la liste entière
L'instruction free détruit une cellule de la mémoire dénitivement, si on
commence à utiliser cette instruction sur toute la liste, la liste sera supprimée
entièrement.
6
DeleteList( var head : list)
p, r : list;
Procédure
Début
p ← head;
((p 6= nil))
r ← p ↑ .next;
f ree(p);
p ← r;
Tant que
faire
Fait
Fin
Algorithme 5 Suppression de la liste
Pour supprimer un élément de la liste, il faut le rechercher en premier
lieu et le détruire si il existe tout en gardant le chainage de la liste.
2.3.5 Liste doublement chainée
Dans cette liste, on ajoute un lien vers l'élément précédent (le prédécesseur). Ainsi on peut accéder indiéremment dans les deux sens : de successeur en successeur, ou de prédécesseur en prédécesseur. Cette structure
est coûteuse en mémoire par rapport la liste simplement chaînée car on a
plus d'instructions pour la mise à jour : une insertion coûte quatre copies de
pointeurs, contre deux dans la liste simplement chaînée.
12
99
37
Figure 2.5 Représentation d'une liste doublement chainée
Cette liste permet d'opérer une insertion avant ou après un élément, sans la
nécessité d'un pointeur sur le voisin, alors qu'une liste simplement chaînée
n'autorise une insertion qu'à une seule position par rapport à un élément :
en successeur ou (exclusivement) en prédécesseur.
7
implémentation d'une liste doublement chainnée
En plus de la déclaration d'une liste simple chainage, on ajoute un pointeur vers le précédant.
type l i s t =^p o i n t e u r
v a l u e : i n t e g e r ; ( ∗ ou n ' i m p o r t e q u e l a u t r e type ∗ )
next , p r e v i o u s : l i s t ;
end ;
Listing 2.2 déclaration d'une liste à double chainage
2.3.6 Liste circulaire
Une liste circulaire est une liste chaînée qui forme une boucle (ou chaîne
fermée). Le début ou la n de chaîne disparaît. Une liste circulaire est construite
lorsqu'on réalise le chainage entre le dernier élément et le premier élément
(dans de cas d'une liste doublement chaînée, alors le premier élément est
chainé avec le dernier). L'utilisation de telle liste exige des précautions pour
éviter les parcours innis.
2
3
1
4
5
Figure 2.6 Liste chainée circulaire
8
Chapitre 3
piles et les les
Les piles et les les sont des structures de données qu'on peut imaginer
comme un sac. Ce sac peut orir plusieurs opérations de base, parmi ces
opération :
tester si il est vide,
l'ajouter un élément,
retirer un élément du sac (Seulement et seulement si le sac est vide).
Le sac est une structure impérative : un sac se modie au cours du temps.
On distingue les piles et les les par la relation entre éléments ajoutés et
éléments enlevés. Dans le cas d'une pile, c'est le dernier élément ajouté qui
est retiré, alors que dans le cas d'une le c'est le premier élément ajouté qui
est retiré. On dit que la pile est une structure LIFO (Last-In First-Out), et
que la le est une structure FIFO (First-In First-Out).
Si on représente pile et le par des tas de cases (3.1), on voit que la le
possède une entrée et une sortie, tandis que la pile possède un sommet, où
sont ajoutés et d'où sont retirés les éléments.
3.0.7 Utilité de pile et le
La pile est plus informatique de nature. La politique dernier-arrivé, premierservi n'est pas très populaire dans la vie quotidienne . Elle correspond pourtant à une situation courante, la survenue de tâches de plus en plus urgentes.
Les piles modélisent aussi tout système où l'entrée et la sortie se font par
le même passage obligé, par exemple : Voitures dans un garage qui a une
seule porte. La le est peut-être la structure la plus immédiate, elle modélise directement les les d'attente gérées selon la politique premier-arrivé,
premier-servi.
9
Sommet de pile
Entree de la file
Sortie de la file
Une file F
Base
Une pile P
Figure 3.1 Une pile (l'insertion et la suppression se fait du même coté),
une le (ajouter et retirer de côtés opposés).
3.0.8 implémentation et primitive
On peut implémenter une pile par deux structure :statique ou contiguë
(tableau) ou dynamique ou non-contigüe (liste chainée).
Par Tableau :
Par liste :
10
Téléchargement