Académique Documents
Professionnel Documents
Culture Documents
2
Et bien ceci est possible, parce que les éléments du tableau sont stockés
en mémoire l’un à coté de l’autre, ils sont voisins, il sont adjacents. On
dit que les éléments du tableau sont contigus.
Au fait c’est une manière de représentation des données, on parle de la
représentation contigüe.
L’avantage principal de la représentation contigüe, est qu’à partir d’une
adresse de base, on peut accéder directement à un élément de
l’ensemble juste en ayant sa position (son indice). Ce qui permet
d’accélérer l’accès aux données.
Elémen
t s
E1 E2 E3 E4 E5 E6 E7 E8
1 2 3 4 5 6 7 8
es
Indic
4
2- La mise à jour des données
Alors si jamais on veut supprimer un élément ou insérer dans le mesure
du possible (si l’espace le permet), on doit faire toute une gymnastique
qui prend beaucoup de temps.
Oui on doit faire un décalage de tous les éléments.
Trèèèès bien, voici un exemple:
Soit un tableau de 10 éléments. Pour supprimer le deuxième élément,
on doit décaler tous les éléments à partir du troisième d’une case à
gauche (donc 8 décalages), ensuite on réduit la taille exacte (N) du
tableau
4 -1 3 8 1 -8 13 15 7 30
4 -1
3 83 81 1
-8 -8
13 13
15 15
7 7
30 30
3 8 1 -8 13 15 7 30
Alors ça c’est pour un tableau de 10, imaginez le travail à faire pour un
tableau de 1000 ???!!!! La même chose se fait pour l’insertion.
5
Donc que ça soit Statique ou Dynamique
La représentation Contigüe possède un avantage très intéressant
(l’accès rapide aux données), mais elle a un inconvénient majeur dans le
cas d’une mise à jour des données.
5
29 3
5
29 3 19
8 29
8 19
fin 3
Je repose la question, quel est
le numéro du troisième ?
Alors, le premier c’est 5, son voisin le deuxième, c’est 19 ensuite son
voisin le troisième c’est le numéro 3.
Bien, vous voyez donc, maintenant le lien devient explicite, vous le
voyez.
9
En effet, dans la nouvelle situation, il existe un lien de chainage explicite
entre ces personnes:
5
29 3 3
19
8 29
8 19
fin 3
Indices 1 2 3 4 5 6 7 8 9
Représentation
Contigüe V Chainée
(Tableaux) S (Listes)
16
Manipulation Listes Chaînées
Le type liste n’est pas un type prédéfini, c’est l’utilisateur qui le définit
de sa manière, il faut juste respecter la syntaxe de déclaration.
La manipulation, dépend donc du problème à résoudre. Cependant il y a
des opérations standards qu’on peut retrouver dans différents
problèmes.
Nous allons voir principalement, la création des listes, l’insertion et la
suppression et quelques applications.
Une remarque importante lorsqu’on manipule une liste, il faut retenir
que le premier élément de la liste (Tête de liste) est le seul point d’accès
à la liste, et il ne faut surtout pas le perdre, car si on le perd, tous les
autres éléments seront perdus.
Si on perd la Tête on devient Fou
Pour tout ce qui suit, on va utiliser une liste d’entiers, mais le principe
des algorithmes reste le même pour tout autre type d’élément de la
liste.
17
Déclaration
Type Pliste = ^ Eliste;
Eliste = Enregistrement
Info : entier;
Suiv : Pliste;
Fin;
1- Création des listes chainées
Il existe deux modes de création d’une liste chainée:
a- LIFO (Last In First Out) : dans ce cas chaque élément ajouté est
placé en tête de liste, et donc le dernier élément ajouté sera le
premier de la liste.
b- FIFO (First In First Out) : dans ce cas chaque élément ajouté est
placé à la fin de la liste, et donc le premier élément ajouté sera le
premier de la liste.
18
Création LIFO (Last In First Out)
Pour créer une liste en mode LIFO, on utilise deux Pointeurs:
- Un pointeur pour la Tête de liste.
- Un pointeur intermédiaire pour créer les éléments.
L’opération passe par les étapes suivantes:
Soient T et P les deux pointeurs à utiliser.
1- Initialiser la tête T à Nil. T Nil ;
2- Créer un maillon avec P. Allouer(P);
3- Remplir la partie information. Lire(P^.Info);
4- Enchainer avec la tête T. P^.Suiv T;
5- Transmettre l’adresse de P à T. T P;
6- Aller à 2 pour créer l’élément suivant (boucle de création)
Exemple
Soit à créer une liste composée des éléments : 5 - 3 - 6
Donc le premier élément de la liste sera 6.
19
0- Var T,P : Pliste; Fin de la première itération:
1- T Nil ; T (Tête) pointe vers le premier élément @1 (5)
2- Allouer(P); Le suivant de 5 est Nil (donc c’est aussi le
3- Lire(P^.Info); dernier).
4- P^.Suiv T; P pointe aussi vers 5 ( ne dérange pas).
5- T P;
6- Aller à 2 pour créer l’élément suivant (boucle de création).
On va donc suivre ces étapes pour créer la liste : 5 - 3 - 6
Créer 2 espaces statiques ayant @T @1
Nil @P @1
pour adresses @T et @P
Créer un espace dynamique pour un
maillon (2 champs). Soit à l’adresse @1
@1, puis mettre @1 dans P (@P) 5
Lecture de 5 Nil
Transmettre Nil au champ Mettre P (@1) dans T
Suivant de l’adresse @1 T pointe vers @1
20
Deuxième Itération : Ajouter 3
0- Var T,P : Pliste;
1- T Nil ; Fin de la deuxième itération:
2- Allouer(P); T (Tête) pointe vers le deuxième élément @2 (3)
3- Lire(P^.Info); Le suivant de 3 est 5.
4- P^.Suiv T; P pointe aussi vers 3 ( ne dérange pas).
5- T P;
6- Aller à 2 pour créer l’élément suivant (boucle de création).
la liste à créer : 5 - 3 - 6
Créer 2eme maillon (@2) @1
@T @2 @P @2@1
@2
Nouveau lien pour P
Lecture de 3
Transmettre @1 au champ
@2 @1
Suivant de l’adresse @2 3 5
Chainage de @2 vers @1 @1 Nil
Mettre P (@2) dans T
T pointe vers @2
Nouveau chainage pour T 21
Deuxième Itération : Ajouter 6
0- Var T,P : Pliste;
1- T Nil ; Fin de l’opération
2- Allouer(P); T (Tête) pointe vers le troisième élément @3 (6)
3- Lire(P^.Info); Le suivant de 6 est 3, le suivant de 3 est 5.
4- P^.Suiv T; P pointe aussi vers 6 ( ne dérange pas).
5- T P;
6- Aller à 2 pour créer l’élément suivant (boucle de création).
la liste à créer : 5 - 3 - 6
Créer 3eme maillon (@3) @3
@T @2
@3 @P @2
Nouveau lien pour P
Lecture de 6
Transmettre @2 au @3 @2 @1
6 3 5
Suivant de l’adresse @3
Chainage de @3 vers @2 @2 @1 Nil
Mettre P (@3) dans T, T pointe vers @3; Nouveau chainage pour T
En ignorant le pointeur intermédiaire P, la liste de tête T sera : 22
Algorithme de création LIFO
L’algorithme permettant de créer un liste de N entiers peut donc s’écrire
Algorithme CreerLifo;
Var T,P : Pliste;
I,N : entier;
Debut
Lire(N); //nombre d’éléments de la liste
T ← Nil ; //initialiser à vide
Pour I ← 1 à N //boucle de création
Faire
Allouer(P);
Lire(P^.Info);
P^.Suiv ← T;
T ← P;
Fait;
Fin.
23
Algorithme de création LIFO
On peut transformer cet algorithme en procédure avec 2 paramètres
T et N, ils seront donc enlevés des variables locales.
Procedure CreerLifo(E/S/ T:Pliste ; E/ N : entier);
Var P : Pliste;
I : entier;
Debut
T ← Nil ; //initialiser à vide
Pour I ← 1 à N //boucle de création
Faire
Allouer(P);
Lire(P^.Info);
P^.Suiv ← T;
T ← P;
Fait;
Fin;
24
Création FIFO (First In First Out)
Pour créer une liste en FIFO, il faut d’abord créer la tête, ensuite créer
les autres éléments puis les enchainer à la tête, pour cela on utilise
trois Pointeurs:
- Un pointeur pour la Tête de liste (T).
- Un pointeur intermédiaire (P) pour créer les éléments.
- Un pointeur pour sauvegarder le dernier élément créé (Q).
L’opération passe par les étapes suivantes:
Soient T, P et Q les trois pointeurs à utiliser.
1- Initialiser la tête T à Nil.
2- Créer la tête T.
3- Initialiser Q avec T. (Q représente dernier élément créé : Queue)
4- Créer un maillon P.
5- Enchainer avec Q (ajouter P à la fin)
6- Affecter P à Q. (P devient le dernier élément)
7- Aller à 4 pour créer l’élément suivant. (boucle de création)
8- Affecter Nil au suivant de Q. (mettre fin à la liste)
25
Exemple
Soit à créer une liste composée des éléments : 5 - 3 - 6
Donc le premier élément de la liste sera 5.
Création du premier élément (Tête)
Créer 3 espaces statiques ayant
0- Var T,P,Q : Pliste;
pour adresses @T , @Q et @P
1- T Nil ;
2.1- Allouer(T); Créer un espace dynamique pour un
maillon (2 champs). Soit à l’adresse
2.2- Lire(T^.Info);
@1, puis mettre @1 dans T (@T)
3- Q T;
Lecture de 5
@T @1
Nil @Q @1 @P
@T @1 @Q @1
@2 @P @2
@T @1 @Q @2
@3 @P @2
@3
@1 5 @2 3 @3 6
@2 @3
28
Créer les autres éléments (3 – 6)
Deuxième itération : Ajouter 6
4.1- Allouer(P); Fin de la boucle, mettre le suivant de Q (@3) à Nil
4.2- Lire(P^.Info);
5- Q^.Suiv P; Fin de l’opération:
6- Q P; T (Tête) pointe vers le premier élément @1 (5).
7- Boucle Le suivant de 5 est 3, Le suivant de 3 est 6.
8- Q^.Suiv Nil; P et Q pointent vers 6 ( ne dérange pas).
@T @1 @Q @3 @P @3
@1 5 @2 3 @3 6
@2 @3 Nil
8 5 -1 2 Nil
Bon, FIFO ou LIFO sont des modes de création, et non pas une
caractéristique de la liste. Donc, une fois créée, on ne cherche pas à
savoir comment elle a été créée. L’essentiel, on a une suite d’éléments
avec une Tête comme point d’accès.
Alors, on passe maintenant à l’insertion dans une liste. On suppose
qu’on à déjà une liste à laquelle on veut ajouter un élément.
32
2- Insertion dans une liste chainée
Soit T la tête d’une liste donnée, et X un élément (partie info) à insérer
dans cette liste.
Trois cas se présentent pour l’insertion:
1- Insérer au début.
2- Insérer à la fin.
3-Insérer au milieu.
Insérer au début ou à la fin, c’est clair, mais le milieu ?! Comment
on va le définir ?
Bien, quand on dit milieu, ce n’est pas dans le sens moitié, mais c’est
quelque part dans la liste, autre que le début et la fin.
Comment le définir ? Là c’est le cas d’utilisation qui le définit, ça peut
être une position (Ex: insérer à la 3 position), comme ça peut être avant
ou après une valeur donnée, ou encore avant ou après une adresse
donnée,...
Ce qui nous intéresse c’est le principe d’insertion au milieu,
indépendamment du cas de figure.
33
2.1- Insertion au début
Pour insérer au début, on utilise un pointeur intermédiaire (P) et on
passe par les étapes suivantes:
1- Créer l’élément contenant X. Allouer(P) ; P^.Info ← X;
2- Etablir un lien de chainage entre P et T. P^.Suiv ← T ;
3- Déplacer la Tête (T) vers P. T←P;
ATTENTION, l’ordre des actions est très important
Exemple: Soit la liste suivante {13,-5,2}, et on veut insérer X=7 au début
1-
2- @P @4 @T @4
@1
3-
@4 7 @1 13 @2 -5 @3 2
@1 @2 @3 Nil
@4 7 @5 13 @6 -5 @7 2
@5 @6
@x @7 @8
0- Recherche Q
1- Créer X
2- Lier P au Suiv de Q @x
3- Lier Q à P 9
@6
@P @x
39
Algorithme d’insertion au milieu
On va donner juste les actions d’insertion proprement dites, on
considère qu’on a le pointeur Q (après une recherche). Ensuite on va
donner un cas d’insertion avec un type de recherche.
Algorithme InsertMilieu;
----
Debut
---
// Actions de recherche, qui donne Q
Allouer(P);
P^.Info ← X;
P^.Suiv ← Q^.Suiv;
Q^.Suiv ← P;
---
Fin;
40
Exemple de recherches
Recherche de l’Adresse d’une Position
Etant donnée une position K, cette recherche renvoie l’adresse
(pointeur) de l’élément situé à cette position. Si la position n’existe pas,
elle revoie Nil.
Fonction AdressePos(E/ T : Pliste; E/ K : entier) : Pliste;
Var P : Pliste;
Debut
P ← T;
Tantque P ≠ Nil Et K>1
Faire P ← P^.Suiv; K ← K – 1; Fait;
AdressePos ← P;
Fin;
Utilisation
Si on veut insérer Après une position Y : Q ← AdressePos(T,Y);
Si on veut insérer Avant une position Y : Q ← AdressePos(T,Y-1);
41
Recherche de l’Adresse d’une Valeur
Etant donnée une valeur V, cette recherche renvoie l’adresse (pointeur)
de l’élément égale à cette valeur. Si la valeur V n’existe pas, elle revoie
Nil.
Fonction AdresseVal(E/ T : Pliste; E/ V : entier) : Pliste;
Var P : Pliste;
Debut
P ← T;
Tantque P ≠ Nil Et P^.Info ≠ V
Faire P ← P^.Suiv; Fait;
AdresseVal ← P;
Fin;
Utilisation
Si on veut insérer Après une valeur Val : Q ← AdresseVal(T,Val);
42
Recherche de l’Adresse du précédent d’une Valeur
Etant donnée une valeur V, cette recherche renvoie l’adresse (pointeur)
du précédent de l’élément égale à cette valeur. Si la valeur V n’existe
pas ou ne possède pas de précédent (Tête), elle revoie Nil.
Fonction AdrPreVal(E/ T : Pliste; E/ V : entier) : Pliste;
Var P,Q : Pliste;
Debut
AdrPreVal ← Nil; Q ← Nil;
Si T ≠ Nil Alors Si T^.Info ≠ V
Alors P ← T; Q ← T^.Suiv;
Tantque Q ≠ Nil Et Q^.Info ≠ V
Faire P ← Q ; Q ← Q^.Suiv; Fait
Fsi;
Si Q≠ Nil Alors AdrPreVal ← P Fsi;
Fsi;
Fin;
Utilisation
Si on veut insérer Avant une valeur Val : Q ← AdrPreVal(T,Val);
43
Exemple d’insertion regroupant différents cas
Soit T une liste d’entiers, écrire une procédure permettant d’insérer un
élément X à la position K.
Dans ce cas, on peut avoir les différents cas possibles (début, fin, milieu)
et même le cas d’erreur (impossible d’insérer : position n’existe pas)
Procedure Insert(E/S/ T : Pliste ; E/ X,K : entier ; S/ INS : booleen);
Var P,Q : Pliste;
Debut
Allouer(P); P^.Suiv ← X; INS ← Vrai; //créer l’élément
Si K<1
Alors INS ← Faux; //impossible d’insérer, pos n’existe pas
Sinon Si K = 1 Alors P^.Suiv ← T ; T ← P //insertion au début
Sinon Q ← AdressePos(T,K-1); //adresse du précédent de pos
Si Q = Nil
Alors INS ← Faux;
Sinon P^.Suiv ← Q^.Suiv ; Q^.Suiv ← P ; //insérer au milieu ou à la fin
Fsi;
Fsi;
Fsi;
Fsi;
Si Non INS Alors Liberer(P) Fsi; //pas d’insertion, annuler l’allocation mémoire
Fin;
44
Exemple d’insertion dans une liste triée
Soit T une liste d’entiers triée par ordre croissant, écrire une procédure
permettant d’insérer un élément X dans cette liste.
Dans ce cas, l’insertion doit respecter la contrainte de l’ordre des
éléments. L’insertion est toujours possible.
Procedure Insert(E/S/ T : Pliste ; E/ X : entier ; );
Var P,Q,C : Pliste;
Debut
Allouer(P); P^.Info ← X; //créer l’élément
Si T = Nil
Alors P^.Suiv ← T ; T ← P
Sinon Si X ≤ T^.Info
Alors P^.Suiv ← T ; T ← P //insertion au début
Sinon Q ← T; C ← T^.Suiv ; //chercher la position d’insertion
Tantque C ≠ Nil Et X > C^.Info Faire Q ← C ; C ← C^.Suiv ; Fait;
P^.Suiv ← Q^.Suiv ; Q^.Suiv ← P ; //insérer au milieu ou à la fin
Fsi;
Fsi;
Fin;
45
Récapitulation de l’insertion
L’insertion d’un élément X dans une liste de Tête T
P^.Suiv ← Q^.Suiv
Nil ; ; P^.Suiv ← Q^.Suiv ;
Q^.Suiv ← P ; Q^.Suiv ← P ;
IDENTIQUE
46
3- Suppression dans une liste chainée
Soit T la tête d’une liste donnée, et X un élément (partie info) à
supprimer de cette liste.
Comme pour l’insertion, là aussi trois cas se présentent :
1- Suppression au début.
2- Suppression à la fin.
3-Suppression au milieu.
Est-ce-que là aussi on peut regrouper la suppression à la fin et
la suppression au milieu ?
Oui, là aussi on peut le faire, et donc je ne vais traiter que deux cas :
début et autre que début
Ce qu’il faut retenir dans la suppression
Il faut toujours chercher le précédent de X (sauf le cas du début).
Comme pour l’insertion, la recherche dépend du cas à traiter.
A la fin de la recherche on à un pointeur Q vers le précédent.
47
3.1- Suppression au début
En général, la suppression consiste à détacher l’élément à supprimer en
mettant à jour le chainage, puis libérer l’espace réservé pour cet
élément.
Pour la suppression au début, on utilise un pointeur intermédiaire (P).
L’opération passe par trois étapes :
1- Sauvegarder le suivante de la tête dans P. P ← T^.Suiv ;
2- Libérer l’espace réservé pour la tête T. Liberer(T);
3- Relier la tête T à P. T←P;
Exemple: Soit la liste suivante {13,-5,2}, et on veut supprimer la tête (13)
1-
@T @2
@1 @P @2
2-
3-
@1 13 @2 -5 @3 2 Fin de l’opération
@2 @3 Nil 13 est supprimé
48
Procédure Suppression au début
La procédure a un seul paramètre T.
T est passé par référence (E/S), car la tête va changer.
Procedure SupprimeDebut(E/S/ T:Pliste);
Var P : Pliste;
Debut
Si T ≠ Nil Alors P← T^.Suiv ; Liberer(T); T ← P Fsi;
Fin;
Remarque
On peut aussi faire: P← T ; T ← T^.Suiv ; Liberer(P)
3.2- Suppression autre que le début
Comme on l’a fait pour l’insertion, on laisse le problème de la recherche
à coté, on considère juste le résultat de cette recherche qui donne un
pointeur Q sur le précédent de l’élément à supprimer.
Soit P le pointeur sur l’élément à supprimer. L’opération passe par deux
étapes seulement:
1- Mettre à jour le suivant de Q. Q^.Suiv ← P^.Suiv ;
2- Libérer l’espace réservé pour P. Liberer(P);
49
Exemple
Soit une partie de la liste {...,7,13,-5,2,…}, et on veut supprimer X=-5
Fin de l’opération
-5 est supprimé @Q @5 @P @6
@4 7 @5 13 @6 -5 @7 2
@5 @6
@7 @7 @8
0- Recherche Q , P
1- Mettre à jour le suivant de Q
2- Libérer l’espace de P
Donc dans le cas d’un algorithme, une fois qu’on à le P et le Q, les deux
actions de suppression seront:
Q^.Suiv ← P^.Suiv ;
Liberer(P);
50
Exemple de suppression regroupant différents cas
Soit T une liste d’entiers, écrire une procédure permettant de supprimer un
élément à la position K.
Dans ce cas, on peut avoir les différents cas possibles (début, fin, milieu) et même
le cas d’erreur (impossible de supprimer : position n’existe pas)
Procedure Supprime(E/S/ T : Pliste ; E/ K : entier ; S/ SUP : booleen);
Var P,Q : Pliste;
Debut
SUP ← Vrai;
Si T ≠ Nil
Alors SUP ← Vrai;
Si K<1
Alors SUP ← Faux; //impossible de supprimer, pos n’existe pas
Sinon Si K = 1 Alors P← T ^.Suiv ; Liberer(T); T ← P //suppression au début
Sinon Q ← AdressePos(T,K-1); //adresse du précédent de pos
Si Q = Nil Alors SUP ← Faux;
Sinon P ← Q^.Suiv ;
Q^.Suiv ← P^.Suiv ; Liberer(P) //milieu ou à la fin
Fsi;
Fsi
Fsi;
Fsi;
Fin;
51
Quelques Applications courantes
Affichage des élément d’une liste
Procedure Affichage(E/ T : Pliste );
Var P : Pliste;
Debut
P←T;
Tantque P ≠ Nil
Faire Ecrire(P^.Info); P ← P^.Suiv ; Fait;
Fin;
Détruire une liste (supprimer tous les éléments)
Procedure Detruire(E/ T : Pliste );
Var P : Pliste;
Debut
Tantque T ≠ Nil
Faire P ← T ; T ← T^.Suiv ; Liberer(P); Fait;
Fin;
52
Trier une liste
Procedure Tri(E/ T : Pliste );
Var P,Q : Pliste; X: entier;
Debut
P←T;
Tantque P^.Suiv ≠ Nil
Faire Q ← P^.Suiv ;
Tantque Q ≠ Nil
Faire Si Q^.Info < P^.Info
Alors X ← P^.Info ; P^.Info ← Q^.Info ; Q^.Info ← X;
Fsi;
Q ← Q^.Suiv ;
Fait;
P ← P^.Suiv ;
Fait;
Fin;
53
brbessaa@gmail.com
54