Uploaded by Basmala M'Hamed Messaoud

1- Résumé sur les listes

advertisement
*** Résumé sur les listes linéaires chainées ***
Note : avant de voir ce document il est nécessaire de voir la video “3- Les listes linéaires chainées SDD et Modèle“ qui existe dans la rubrique “ dans la chaine YouTube : « Algorithmique By Zair »
afin de comprendre la structure d’une liste et maitriser les opérations élémentaires sur les maillons de
la liste.
Ce document contient des exemples sur quelques traitements qu’on peut avoir dans une liste L.
Une liste linéaire chainée (unidirectionnel) est un ensemble de maillons (enregistrements) reliés entre
eux.
Il existe plusieurs types de listes :
1) Liste chainée unidirectionnel : où chaque maillon possède les informations utiles ainsi qu’un
pointeur contenant l’adresse de son suivant, sauf le dernier maillon qui n’a pas de suivant (Nil).
2) Liste chainée circulaire : c’est une liste chainée mais le suivant du dernier maillon est le
premier maillon.
3) Liste chainée bidirectionnel : où chaque maillon possède en plus des informations utiles, un
champ contenant l’adresse du suivant et un champ contenant l’adresse du précédent.
Les deux derniers types de listes seront vus en deuxième année. Donc on s’intéresse seulement à la liste
chainée unidirectionnel.
I) Les listes linéaires chainées :
On distingue 3 classes d’opérations qu’on peut trouver dans le cas des listes :
I. Opérations de consultation : ce sont des opérations qui ne modifient ni les valeurs, ni les
chainages des maillons tel que : l’affichage de la liste, affichage d’un élément qui se trouve à une
position k, calcul de la moyenne, calcul du nombre d’éléments pairs, recherche d’une valeur, …
Soit L un pointeur qui contient l’adresse du premier élément d’une liste qui existe déjà.
On utilise un autre pointeur p qui va contenir à chaque fois l’adresse d’un des éléments de la liste, et qui
va servir pour parcourir les éléments de la liste.
Toutes les opérations de consultation nécessitent l’utilisation d’une boucle qui permet de parcourir
(passer par) tous les éléments de la liste, et qui a la forme suivante :
pL ;
{p est initialisé par l’adresse du premier élément}
tant que (p<>Nil) faire
{tant que p pointe encore sur un élément de la liste, donc on sort de la
boucle lorsque p=Nil c’est-à-dire p ne pointe sur aucun élément}
…………… traitements portants sur la valeur du maillon pointé par p (Val(p)) ………….
pSuiv(p) ;
{p prend l’adresse du prochain maillon (p pointe vers le maillon suivant)}
fait ;
Exemple1 : Affichage de la liste
pL ;
tant que (p<>Nil) faire
Ecrire(Val(p)) ; {Affichage d’un élément}
pSuiv(p) ;
fait ;
i1;
tant que (i<=n) faire
Ecrire(T[i]) ;
{Affichage d’un élément}
ii+1 ;
fait ;
Remarque : On parcourt les éléments d’une liste avec un pointeur qui contient à chaque fois l’adresse d’un
élément, c’est exactement le rôle de l’indice qu’on utilise pour parcourir un vecteur, sauf que l’indice contient à
chaque fois la position d’un élément et non pas son adresse.
Donc ne confondez pas entre un pointeur et un indice.
Exemple2 : copier les éléments d’une liste ne dépassant pas 100 éléments dans un vecteur T.
pL ;
i1 ;
tant que (p<>Nil) faire
T[i]Val(p); {copier la valeur d’un maillon dans une case du vecteur T}
pSuiv(p) ;
ii+1 ;
{On doit avancer dans la liste et dans le vecteur}
fait ;
Exemple3 : calcul de la moyenne
pL ;
s0 ;
cpt0 ;
tant que (p<>Nil) faire
ss+ Val(p);
{Ajout de la valeur d’un élément à la somme}
cptcpt+1 ;
{incrémenter le compteur du nombre d’éléments}
pSuiv(p) ;
fait ;
si (cpt=0) alors
Ecrire(“impossible de calculer la moyenne car la liste est vide“) ;
sinon Moys/cpt ;
Ecrire(“Moy=“, Moy) ;
finsi ;
Exemple4 : recherche d’une valeur val (indiquer si la valeur val existe dans la liste ou non)
pL ;
existefaux ;
{on suppose que val n’existe pas}
tant que (p<>Nil) et (existe=faux) faire {tant que ce n’est pas la fin de la liste et on n’a pas trouvé val}
Si(Val(p)=val) alors existevrai; {On a trouvé la valeur donc on s’arrête}
Sinon pSuiv(p) ; {on avance vers le prochain pour le vérifier}
Finsi ;
fait ;
si (existe=faux) alors
Ecrire(“val n’existe pas“) ;
sinon Ecrire(“val existe“) ;
finsi ;
**********************************************************************************
II. Opérations de modification des valeurs des éléments : par exemple : ajouter 1 à
tous les éléments pairs, faire une rotation à gauche ou à droite des éléments sans modifier les
chainages, trie d’une liste ….
Soit L un pointeur qui contient l’adresse du premier élément d’une liste qui existe déjà.
On utilise un autre pointeur p qui va contenir à chaque fois l’adresse d’un des éléments de la liste, et qui
va servir pour parcourir les éléments de la liste.
Toutes les opérations de modification des valeurs des éléments nécessitent l’utilisation de la boucle de
parcourt qu’on a déjà vue dans les opérations de consultation.
Exemple1 : Ajouter 1 à tous les éléments de rang pair et soustraire 1 à tous les éléments impairs.
pL ; i1;
{i va représenter à chaque fois la position du pointeur p dans la liste}
tant que (p<>Nil) faire
{tant que ce n’est pas la fin de la liste et on n’a pas trouvé val}
Si(i mod 2=0) alors Aff_val(p, Val(p)+1);
finsi ;
Si(Val(p) mod 2<>0) alors Aff_val(p, Val(p)-1); finsi ;
pSuiv(p) ; ii+1 ;
{on avance p et i}
fait ;
Exemple2 : Rotation à droite
Si (Suiv(L) <>Nil) alors {la liste contient au moins 2 éléments}
pSuiv(L);
Tant que(p<>Nil) faire
{On permute à chaque fois la valeur d’un élément avec celle du premier élément en
commençons par le premier}
x Val(L);
Aff_Val(L, Val(p));
Aff_Val(p, x) ;
pSuiv(p) ;
Fait ;
Finsi ;
Exemple3 : Rotation à gauche
Si (Suiv(L) <>Nil) alors
{la liste contient au moins 2 éléments}
x Val(L);
{on copie la valeur du premier élément}
qL ;
pSuiv(L) ;
{à chaque fois p est le suivant de q}
tant que (p<>Nil) faire
Aff_Val(q, Val(p));
{décalage d’une valeur à gauche}
qp; pSuiv(p) ;
{avancer les deux pointeurs}
fait ;
Aff_val(q, x);
{on met la valeur du premier élément (x) dans le dernier élément}
finsi ;
**********************************************************************************
III. Opérations de modification des chainages des éléments :
a. La création d’une liste :
Exemple 1 : on veut créer une liste L à partir de n valeurs lues.
1ère méthode :
- Insertion des éléments à la fin → L’ordre des éléments est préservé.
- On utilise cette méthode dans la plupart des cas sauf si on veut créer une liste inversée.
1) On initialise la liste à vide (LNil ;)
2) Boucle des données (il faut se poser la question quel est le nombre d’éléments à copier dans la liste et à
partir de quoi on les copies) : la boucle varie selon l’exercice
a) Créer un nouveau maillon avec p
b) Attribuer une valeur au nouveau maillon soit en lisant la valeur à partir de l’utilisateur, ou on la
copiant à partir d’un vecteur, matrice, ou une autre liste : peut varier selon l’exercice.
c)
Si La liste est vide (L=Nil) {donc c’est le premier maillon} alors :
L et q pointent avec p
Sinon {ce n’est pas le premier maillon} alors :
Relier le dernier maillon (q) avec le nouveau maillon (p), puis avancer q vers p
3) Si la liste n’est pas vide (L<>Nil) alors : mettre Nil sur le champ suivant du dernier maillon (pointé par p ou q).
Procédure Création (var L : Liste, n :entier) ;
{L pointe sur le premier élément}
Variable
i : entier;
p, q : Liste;
{p pointe sur le nouveau élément, et q sur le dernier}
début
{On initialise L à Nil, c’est pour dire que la liste est vide au départ}
LNil ;
pour i1 à n faire
{car il y a n valeurs à mettre dans la liste}
{création d’un maillon avec p}
pAllouer();
{On va lire une valeur puis on l’affecte au champ Val du maillon (p)}
ecrire("donner une valeur");
lire(x) ;
Aff_Val(p, x) ;
{Si la liste est vide donc le maillon qu’on vient de créer est le premier maillon}
si(L=NIL)
alors
Lp ;
{on pointe L sur le maillon(p), à présent L est différent de Nil}
qp ;
{on avance q vers p car q pointe vers le dernier maillon}
sinon {ce n’est pas le premier maillon}
Aff_Suiv(q, p);
{on relie le dernier maillon (q) avec le nouveau maillon (p)}
qp ;
{on avance q vers p car q pointe vers le dernier maillon}
finsi ;
fait ;
{Si la liste n’est pas vide alors attribuer la valeur Nil au champ suivant du dernier maillon}
Si (L<>Nil) alors
fin
Aff_Suiv(p, Nil);
{ou Aff_Suiv(q, Nil) ;}
finsi ;
2ème méthode :
- Insertion des éléments au début → l’ordre des éléments est inversé.
- On utilise cette méthode dans la plupart des cas sauf si on veut garder l’ordre des valeurs.
1) On initialise la liste à vide (LNil;)
2) Boucle des données (il faut se poser la question quel est le nombre d’éléments à copier dans la
liste ou à partir de quoi on les copies) : la boucle varie selon l’exercice
a) Créer un nouveau maillon avec p
b) Attribuer une valeur au nouveau maillon soit en lisant la valeur à partir de l’utilisateur, ou on la
copiant à partir d’un vecteur, matrice, ou une autre liste : peut varier selon l’exercice.
c) Relier le nouveau (p) avec le premier maillon (L), puis mettre L vers p
Procédure Création (var L : Liste, n :entier) ;
{L pointe vers le premier élément}
Variable
i : entier;
p : Liste;
{p pointe vers le nouveau élément}
début
LNil ;
{On met L à Nil c’est pour dire que la liste est vide au départ}
pour i1 à n faire {car il y a n valeurs à mettre sur la liste}
{création d’un maillon avec p}
pAllouer();
{La valeur du maillon vient de l’utilisateur, donc on va lire valeur puis l’affecter au maillon (p)}
ecrire("donner une valeur");
lire(x) ;
Aff_Val(p, x) ;
{On relie le nouveau maillon (p) avec le premier maillon (L)}
Aff_Suiv(p, L);
{A présent le premier élément a changé (c’est p), alors on met L avec p}
Lp;
Fait;
Fin
Exemple 2 : Créer une liste L à partir des éléments pairs de rang impair d’un vecteur T de taille n (n≤100).
LNil ;
pour i1 à n pas 2 faire {le rang est impair donc i=1, 3, 5….}
si(T[i] mod 2=0) alors
{on copie uniquement les éléments pairs de T}
pAllouer();
Aff_Val (p, T[i]);
si(L=NIL)
alors
Lp ;
qp;
sinon
Aff_Suiv(q , p);
qp;
finsi ;
finsi ;
{Attention à l’emplacement du “finsi;“}
fait ;
Si(L<>Nil) alors
Aff_Suiv(p, Nil);
finsi ;
*******************************************************************************************
****
J’espère que ce fichier va être bénéfique, et je m’excuse en cas d’erreur.
Pour information : Il y a un site google sur internet rédigé par une enseignante de
l’université de Blida1 qui contient des cours, exercices et examens corrigés sur plusieurs
modules (de la deuxième année licence jusqu’au 2ème année master).
https://sites.google.com/a/esi.dz/informatiqueblida/
Donc profitez pendant les vacances, et bon courage pour la suite.
Download