Vous êtes sur la page 1sur 21

Les Pointeurs

1. Définition
Un pointeur est une position mémoire qui contient l'adresse d'une autre position mémoire. Généralement cette
position mémoire est une variable qui contient l'adresse d'une autre variable. Si un pointeur P contient l'adresse
d'une variable A, on dit que 'P pointe vers A'.

Déclaration d'un pointeur


<idf_pointeur> : ^ <type_variable_pointée>;

<idf_pointeur> est le nom de la variable pointeur qui va contenir l'adresse d'une variable de type
< type_variable_pointée>.

Exemple:
p: ^entier;
p est le nom d'un pointeur qui peut contenir l'adresses d'une variable de type entier.

2. Les opérateurs de base

Lors du travail avec des pointeurs, nous avons besoin


- d'un opérateur ' @ ': pour obtenir l'adresse d'une variable.
- d'un opérateur ' ^ ': pour accéder au contenu d'une adresse.

adresse de<NomVariable> fournit l'adresse de la variable <NomVariable>


Exemple:
Dans l'exemple ci-dessous on a 2 variables de type entier i et g et une autre variable p qui est un pointeur vers un
entier.
A l'étape 0 est déclarée le pointeur p comme étant un pointeur vers un entier. A cette étape là, p contient n'importe
quoi (certains compilateurs C initialisent un pointeur a 0 (NULL) lors de sa déclaration mais il ne faut pas se fier
de cela; il faut toujours initialiser un pointeur après sa déclaration).
A l'etape 1 dans p on met l'adresse de i et a l'étape 2 on met dans p l'adresse de g.

algorithme pointeur ;
Var
p:^entier; /* Etape 0 */
i,g: entier;
Debut
i<-- 25;
g <-- 48;
p <-- @i; /* Etape 1 */
p <-- @g; /* Etape 2 */
Fin.

Ci-dessous est montre l’état de la Mémoire Centrale (MC) aux 2 etapes 1 et 2 ou par exemple 0x1524 est l'adresse
(en hexadécimales) en MC de la variable i et 0x1520 est l'adresse en MC de la variable g.

MC Etape 1 MC Etape 2

1
3. Accès à la variable pointée
La variable pointée est accessible en utilisant la syntaxe suivante:
<idf_pointeur> ^
Désigne le contenu de l'adresse référencée par le pointeur <idf_Pointeur>
Comme montre ci-dessous, si p contient l'adresse de i alors (p^) désigne i c'est a dire la variable pointée par p.
Donc si on écrit: p <-- @ i;
alors si on veut mettre i dans g on peut ecrire: g <-- i;
ou bien on peut écrire: g <-- p^;
car (p^) désigne le contenu de p c'est tout simplement i.
Et si on veut mettre 12 dans i on peut ecrire: i <-- 12;
ou bien on peut écrire: p^ <-- 12;
algorithme pointeur2 ;
Var
p:^entier;
i,g:entier;

Debut
i <--- 25 ;
p <--- @i;
g <--- p^; /* Etape 1 */
p^<--- 12; /* Etape 2 */
Fin.
Ci-dessous est montre l’état de la mémoire centrale aux 2 étapes 1 et 2.
MC Etape 1 MC Etape 2

4. Allocation de l'espace mémoire


Problème
Souvent, nous devons travailler avec des données dont nous ne pouvons pas prévoir le nombre et la grandeur lors
de la programmation. Ce serait alors un gaspillage de réserver toujours l'espace maximal prévisible. Il nous faut
donc un moyen de gérer la mémoire lors de l'exécution du programme.
2
L'allocation dynamique permet d'allouer et de libérer de l'espace mémoire durant l'exécution d'un programme.

Syntaxe

Allouer(<idf_pointeur>);
Exemple:
Var
p1: ^ entier;
Debut
Allouer(p1);

Allouer(p1) alloue de l'espace mémoire pour un entier et met son adresse dans p1.

5. Libération de l'espace mémoire


Syntaxe:

Liberer(<idf_pointeur>);
Exemple:
Liberer(p1);

Libérer(p1) libère l'espace mémoire occupé par l'entier dont l'adresse est dans p1.

6. Manipulation des Pointeurs


Initialisation d'un pointeur
Une variable pointeur peut être initialisée de 2 manières: en lui affectant l'adresse d'une variable statique ou bien
en appelant la fonction Allouer(p) de telle manière que p pointe vers une zone mémoire allouée dynamiquement.
Comme les autres types de variable lorsqu'on déclare une variable de type pointeur cette variable contient
n'importe quoi au début. Ainsi c'est une bonne pratique d'initialiser ce pointeur a Nil (NULL en C) pour indiquer
que ce pointeur ne pointe vers aucune zone mémoire.
Exemple:
Algorithme InitPointeurs;
Type
Etudiant=Enregistrement
matricule: Entier;
nom, prenom: chaine[20];
moyenne: Reel;
Fin;

Var
p1,p2:^entier;
p3: ^Etudiant;
X:entier;

3
Debut
p1 <--- @X; /* p1 contient l'adresse mémoire de X */

Allouer(p2); /* p2 contient l'adresse mémoire d'un entier alloué dynamiquement */

Allouer(p3); /* p3 contient l'adresse d'un enregistrement de type Etudiant alloué dynamiquement*/


...
Libérer(p2);
Libérer(p3);
Fin

7. Pointeurs et enregistrement
Exemple:
Algorithme InitPointeurs;
Var
p1,p2:^entier;
p3: ^Etudiant;

Debut
p1 <--- @X; /* p1 contient l'adresse mémoire de X */
Allouer(p2); /* p2 contient l'adresse mémoire d'un entier alloué dynamiquement */
Allouer(p3); /* p3 contient l'adresse d'un enregistrement de type Etudiant alloue dynamiquement
p1^ <--- 12;
p2^ <--- 27;
p3^.matricule <--- 17842;
p3^.nom <--- "Amine";
p3^.prenom <--- "Younes";
p3^.moyenne <--- 12.5;
Ecrire(p1^);
Ecrire(p2^);
Ecrire(p3^.matricule, p3^.nom, p3^.prenom, p3^.moyenne);
Liberer(p2);
Liberer(p3);
p1^ <--- 12;
p2^ <--- 27;
p3^.matricule <--- 17842;
p3^.nom <--- "Amine";
p3^.prenom <--- "Younes";
p3^.moyenne <--- 12.5;

4
Fin.

Les listes chainées :


Définition :Les listes chaînées sont des structures de données semblables aux tableaux sauf que l'accès à un
élément ne se fait pas par index mais à l'aide d'un pointeur.
Une liste est une structure d'éléments de même type. Chaque élément est composé de 2 parties: une partie qui
contient l'information de l'élément qui peut être de type simple ou composé et une partie qui contient l'adresse de
l'élément qui suit appelée lien de chainage. Ce lien est un pointeur qui est l'adresse de l'élément suivant. Ainsi à
partir de chaque élément on peut accéder à l'élément suivant.

5
En revanche, par rapport aux tableaux où les éléments sont contigus dans la mémoire, les éléments d'une liste sont
éparpillés dans la mémoire.
La liaison entre les éléments se fait grâce à un pointeur.

Caractéristiques des listes chainées :


Une lise est composée d’abords d’une adresse de départ qui référence le premier élément de cette liste(tête de
liste), chaque élément de la liste dispose une référence vers l’élément suivant. Le dernier élément contient comme
référence sur l’enregistrement suivant la valeur nulle.
Pour accéder à une valeur, on part toujours de la première valeur. A partir de la tête on peut accéder à tous les
éléments successivement jusqu’à retrouver l’élément recherché .si on trouve la référence Nulle cela signifie que la
valeur recherchée n'existe pas.

Création d'une Liste


Supposons qu'on veut écrire un algorithme qui crée une liste d'entiers. On va demander au début à l'utilisateur de
nous donner combien d'éléments la liste va contenir au début. On va mettre cette valeur dans une variable qu'on
appellera N.
Supposons que l’utilisateur donne N égale à 4, ensuite il nous donne les valeurs -15, 44, 88, 12 dans cet ordre.
Ces valeurs sont les valeurs qu'on va mettre dans le champ val de chaque élément.

Il y’a 2 manières de créer cette liste.


La première en ajoutant chaque valeur que l’utilisateur donne en fin de liste et dans ce cas la liste créée aura le
même ordre que celui donne par l’utilisateur. On dit que c’est une liste FIFO (First In/First out) ou bien premier
arrivé/premier servi. Dans l’exemple ci-dessus la liste sera {-15, 44, 88, 12}
La seconde manière de créer la liste est d’ajouter chaque valeur donnée par l’utilisateur en tête de liste (plutôt que
en fin de liste) et dans ce cas la liste crée aura l’ordre inverse de l’ordre donne par l’utilisateur. On dit que c’est
une liste LIFO (Last In/First Out) ou bien dernier arrive/premier servi. Dans l’exemple ci-dessus la liste sera { 88,
44, -15}
Création d'une Liste LIFO
N=3 et l'utilisateur donne les valeurs -15, 44, 88, dans cet ordre.
Au début la liste est vide, donc tête est mise a Nil.
6
Chaque fois que l'utilisateur donne une valeur, la valeur est ajoutée en tête de liste.
l’élément n’existe pas.
Algorithme CreationListeLiFo;
Type
liste=Enregistrement
val :entier ;
suivant : ^liste;
Fin ;
Var
tete : ^liste;
N: Entier;

Fonction CreerListeLifo(N: Entier) : ^liste


var
p,L:^liste;
I:entier;
Debut
L <--- Nil;//L correspond à la tete
Pour I <--- 1 a N
Faire
Allouer(p);
Ecrire("Donner ", I , " Valeur");
Lire(p^.val);
p^.suivant <--- L;
L <--- p;
Fait
Retourner L;
Fin;

Procedure AfficherListe(E/ L : Pliste)


Debut
Ecrire("Liste:");
Tant Que (L <> Nil)
Faire
Ecrire(L^.val);
L <--- L^.suivant;
Fait
Ecrire("Fin de Liste");
Fin;

Debut
7
Repeter
Ecrire("Donner Nombre d'éléments de la liste");
Lire(N);
Jusqu'a (N > 0);// N= mombre d'elmt de la liste

tete <--- CreerListeLifo(N);


AfficherListe(tete);
Fin

Algorithme CreationListeFiFo;
Type Pliste=^Liste ;
Liste=Enregistrement
val :entier ;
suivant : Pliste;
Fin ;
Var
tete : Pliste;
N: Entier;

Fonction CreerListeFifo(N: Entier) : Pliste;


Var
L, p, prec : Pliste; /* prec représente pointeur vers le précédent */
I : Entier;
Debut
Si N >0
Alors
Allouer(p);
Ecrire("Donner la Première Valeur");
Lire(p^.val);
L <--- p;
prec <--- p; /* le précédent du 2eme est le 1er élément */
Pour I <--- 2 a N
Faire
Allouer(p);
Ecrire("Donner ", I , " Valeur");
Lire(p^.val);
prec^.suivant <--- p; /* le suivant du précédent est le courant p*/
prec <--- p; /* le courant devient le précédent pour le prochain */
Fait
p^.suivant <--- Nil; /* Mettre Nil dans le suivant du dernier élément*/
Fsi;
Retourner L;
Fin;

8
Procedure AfficherListe(E/ L : Pliste)
Debut
Ecrire("Liste:");
Tant Que (L <> Nil)
Faire
Ecrire(L^.val);
L <--- L^.suivant;
Fait
Ecrire("Fin de Liste");
Fin;

Debut
Repeter
Ecrire("Donner Nombre d'éléments de la liste");
Lire(N);
Jusqu'a (N > 0);

tete <--- CreerListeFifo(N);


AfficherListe(tete);
Fin

Solution des exercices de la série

EXERCICE 1 :
Soit une matrice (N,M) d’entiers. Ecrire un algorithme qui génère deux listes à partir de cette matrice.
1- La première regroupe les maximums des lignes (FIFO);
2- Et, la deuxième la somme des colonnes (LIFO).

Algorithme exo1_liste ;
Type Pliste=^EListe ;
EListe=Enregistrement
val :entier ;
suivant :Pliste ;
Fin ;
Var
I,J,N,M, Max, S: entier ;
P, prec, teteListeFifo, teteListeLifo: Pliste;
A : Tableau[1..20,1..30] de entier;

9
Début
Repeter Lire(N) ; Jusqu’à (N>0) et (N≤20) ;
Repeter Lire(M) ; Jusqu’à (M>0) et (M≤30) ;

//Lecture de la Matrice
Pour I ←1 à N Faire
Pour J ←1 à M Faire
Lire(A[I,J]) ;
Fait;
Fait ;

//Création de la liste FIFO contenant les maximums des lignes


//traitement de la tête de la liste Fifo,
teteListeFifo ← Nil;

Max←A[1,1]; /* chercher le MAX de la ligne I=1


Pour J ←2 à M Faire
Si(A[1,J]>Max) Alors Max← A[1,J];Fsi;
Fait;
Allouer (P);

P ^.val←Max; J
teteListeFifo ← P; I
prec← P;

//traitement des autres éléments de la matrice


Pour I ←2 à N Faire
Max=A[I,1];
Pour J ←2 à M Faire
Si(A[I,J]>Max) Alors Max← A[I,J]; Fsi;
Fait;
//On insère le Max dans la liste Fifo
allouer (P);
P ^.val←Max;
prec^.suivant←P;
prec← P;

Fait;
prec ^.suivant←Nil;

10
/*création de la liste LIFO qui contient la somme des colonnes .
On traite pas la tête à part car tous les éléments se traitent de la même façon.*/
teteListeLifo ← Nil;

Pour J ←1 à M Faire
S← 0;
Pour I ←1 à N Faire

S← S+A[I,J];
Fait;
//On insère le S dans la liste Lifo
allouer (P);
P ^.val←S;
P ^.suivant← teteListeLifo;
teteListeLifo ← P;

Fait;
Fin.

EXERCICE 2 :

Soit une liste d’entiers L, écrire les actions paramétrées suivantes permettant :
1- La suppression des doublons (éléments identiques) ;
2- La suppression de la valeur minimale d'une liste;
3- La création de la liste miroir de L (avec ensuite sans création d’une nouvelle liste) ;
4- La fusion de deux listes triées d’entiers L1 et L2 en une liste triée L3 (avec ensuite sans création d’une
nouvelle liste);
Type Pliste=^EListe ;
EListe=Enregistrement
Val :entier ;
Suiv :Pliste ;
Fin ;
c) La suppression des doublons (éléments identiques) ;

11
Procedure SupDouble(E/L :Pliste) ;
Var P, Q, PREC :Pliste ;
Debut
Si L<>Nil
Alors
P←L ;
Tantque P^.Suiv<>Nil
Faire Q←P^.Suiv ; PREC←P ; /*on cherche dans Q l'identique de P, et on sauvegarde dans
PREC le précédent de Q*/
Tantque Q≠Nil
Faire Si Q^.Val=P^.Val /*On a trouvé un élément identique on le supprime*/
Alors PREC^.Suiv←Q^.Suiv ;
Libérer(Q) ;
Q← PREC^.Suiv; Q← Q^.Suiv;
Sinon PREC←Q ; /*Avancer dans la liste*/
Q←Q^.Suiv
Fsi ;
Fait ;
P←P^.Suiv ;
Fait
Fsi ;
Fin ;

d) La suppression de la valeur minimale d'une liste;

fonction SupprimerMin(L: pList): pList;

Var
pMin, pMinPrcd ,p, prcd : pList;
Debut
Si (L <> Nil) Alors /* la liste contient au moins un élément*/
pMin <--- L; /* Considérer le Min comme le 1er élément */
pMinPrcd <--- Nil;
p <--- L^.svt; /* sauvegarder dans pMin l'@ de l'élément à supprimer et dans pMinPrcd son
précédent pour pouvoir faire le chainage
on parcourt la liste avec p et prcd */
prcd <--- L;
Tant Que (p <> Nil)

12
Faire
Si (p^.val < pMin^.val) Alors
pMin <--- p;
pMinPrcd <--- prcd;
Fsi
prcd <--- p;
p <--- p^.svt;
Fait
Si (pMin = L) alors /* Le minimum est le premier élément de la liste */
L <--- L^.svt;
Sinon
pMinPrcd^.svt <--- pMin^.svt;
Fsi
Liberer(pMin);
sinon ecrire ("liste vide suppression impossible");
Fsi
Retourner L;
Fin;

e) La création de la liste miroir de L (avec ensuite sans création d’une nouvelle liste)
Avec Allocation :
Fonction creationListeMiroirAvecNouvelleListe(L: pList) : pList
Var 1 8 -5 3 la liste miroir 3 -5 8 1
P, L_miroir : pList;
Debut
L_miroir <--- Nil; /* parcourir les éléments de la liste 1 et ajouter chaque élément en tête de la liste 2 de
cette façon on obtient une liste inversée*/
Tant Que (L <> Nil)
Faire Allouer(P) ;
P^.Val←L^.Val ;
P^.Suiv← L_miroir ;
L_miroir ←P ;
L←L^.Suiv ;
Fait ;
retourner L_miroir;
13
Fin;

Sans Allocation: Créer une liste miroir de L sans nouvelles allocation (ça revient à inverser la liste).
Procedure creationListeMiroirSansNouvelleListe(E/S L: pList) : pList
Var
P, Prec, Suiv : pList;
Debut
/* initialiser Prec a Nil. mettre dans p l'adresse du 1er élément de la liste
Chaque élément va avoir son suivant le précédent de la liste originale,
Le premier élément de la liste originale aura comme suivant Nil */
P <--- L;
Prec <--- Nil;
Tant Que (P <> Nil)
Faire
/* le courant est p, sauvegarder dans Suiv l'adresse du suivant */
Suiv <--- P^.suiv;
P^.suiv <--- Prec; /* le suivant de p devient le précédent */
Prec <--- P; /* à la prochaine itération le courant devient le précédent */
P <--- Suiv; /* et le suivant devient le courant */
Fait
L<-- Prec; // la tête de la liste miroire
Fin;

f) La fusion de deux listes triées d’entiers L1 et L2 en une liste triée L3 (avec ensuite sans création d’une
nouvelle liste);
Fonction FusionL1L2AvecAlloc(L1, L2: pList) : pList
Var
L, p, prec: pList;
Debut
Si ((L1 <> Nil) et (L2 <> Nil)) Alors
Allouer(p);
Si (L1^.val < L2^.val) Alors
p^.val <--- L1^.val; /*on aurai pu faire Allouer(L); L^.val <--- L1^.val; */
L1 <--- L1^.svt;
Sinon
14
p^.val <--- L2^.val;
L2 <--- L2^.svt;
Fsi ;
L <--- p; // L la tête de la nouvelle liste
prec <--- p; // nouvelle liste FIFO, on fait toujours des insertion en fin, on aura besoins du précédent
Tant Que ((L1 <> Nil) et (L2 <> Nil))
Faire
Allouer(p);
Si (L1^val < L2^.val) alors
p^.val <--- L1^.val;
L1 <--- L1^.svt;
Sinon
p^.val <--- L2^.val;
L2 <--- L2^.svt;
Fsi ;
prec^.svt <--- p;
prec <--- p;
Fait ;
/* Une des deux listes L1 ou L2 est terminée. Il faut ajouter les valeurs qui manquent de L1 ou L2 */
Tant Que (L1 <> Nil)
Faire
Allouer(p);
p^.val <--- L1^.val;
L1 <--- L1^.svt;
prec^.svt <--- p;
prec <--- p;
Fait
Tant Que (L2 <> Nil)
Faire
Allouer(p);
p^.val <--- L2^.val;
L2 <--- L2^.svt;
prec^.svt <--- p;

15
prec <--- p;
Fait
prec^.svt <--- Nil;
Sinon /*le sinon du premier Si ((L1 <> Nil) et (L2 <> Nil)) donc ou bien L1=Nil ou L2=Nil ou les deux sont
vides à l'entrée*/
Si (L1 <> Nil) alors /* liste L2 vide
/* Créer la liste L qui contient tous les éléments de L1, mais le traitement du premier est à part!*/
Allouer(p);
p^.val <--- L1^.val;
L1 <--- L1^.svt;
L <--- p;
prec <--- p;
/* Ajouter les éléments après le 1er élément de L1 */
Tant Que (L1 <> Nil)
Faire
Allouer(p);
p^.val <--- L1^.val;
L1 <--- L1^.svt;
prec^.svt <--- p;
prec <--- p;
Fait
prec^.svt <--- Nil; //dernier element
Sinon /* le sinon de Si (L1 <> Nil) donc L1=Nil
Si (L2 <> Nil) alors
/* Allouer le 1er element */
Allouer(p);
p^.val <--- L2^.val;
L2 <--- L2^.svt;
L <--- p;
prec <--- p;
/* Ajouter les éléments apres le 1er elements de L2 */
Tant Que (L2 <> Nil)
Faire

16
Allouer(p);
p^.val <--- L2^.val;
L2 <--- L2^.svt;
prec^.svt <--- p;
prec <--- p;
Fait
prec^.svt <--- Nil;
Sinon /* Cas ou L1=Nil et L2=Nil */
L <--- Nil;
Fsi
Fsi
Fsi
Retourner L;
Fin;

Fonction FusionL1L2SansAlloc(L1, L2: pList) : pList


/* Sans nouvelle allocation veut dire qu'on change juste les liens entre les éléments de L1 et L2 pour garder
une liste fusionnée et triée, On fait pas de nouvelles allocations on utilise les deux listes*/
Var
L, prec: pList;
Debut
Si ((L1 <> Nil) et (L2 <> Nil)) alors
/* Mettre l'adresse du plus petit dans L */
Si (L1^val < L2^.val) alors
L <--- L1;
L1 <--- L1^.svt;
Sinon
L <--- L2;
L2 <--- L2^.svt;
Fsi
prec <--- L;
Tant Que ((L1 <> Nil) et (L2 <> Nil))

17
Faire
Si (L1^val < L2^.val) Alors
prec^.svt <--- L1;
L1 <--- L1^.svt;
Sinon
prec^.svt <--- L2;
L2 <--- L2^.svt;
Fsi
prec <--- prec^.svt;
Fait
/* Ajouter les liens qui manquent de L1 ou L2 */
Si (L1 <> Nil) alors
prec^.svt <--- L1;
Sinon
prec^.svt <--- L2;
Fsi
Sinon /* sinon du Si ((L1 <> Nil) et (L2 <> Nil))*/
Si (L1 <> Nil) alors
L <--- L1;
Sinon
L <--- L2;
Fsi
Fsi
Retourner L;
Fin;

EXERCICE 3 :
Soit L une liste d’entiers positifs. Ecrire une procédure qui permet d’éclater la liste L en deux listes : Lp contenant
les entiers pairs et Li contenant les entiers impairs. (Sans création de nouvelles listes)

Procedure Eclate(E/ L :Pliste ; S/ Lpair,Limp :Pliste) ;


Var Prec_pair, Prec_imp :Pliste ;
Debut
Lpair ←Nil ; Limp←Nil ;
Tantque L≠Nil
Faire Si L^.Val MOD 2=0 Alors /*vérifier si la tête Lpair est créée
Si Lpair =Nil Alors Lpair←L ;
18
Prec_pair ←L
Sinon Prec_pair ^.Suiv←L ;
Prec_pair ←L
Fsi
Sinon /*vérifier si la tête Limp est créée
Si Limp =Nil Alors Limp←L ;
Prec_imp ←L
Sinon Prec_imp ^.Suiv←L ;
Prec_imp ←L
Fsi
Fsi ;
L←L^.Suiv ;
Fait ;
Si Lpair ≠Nil Alors Prec_pair ^.Suiv←Nil Fsi ;
Si Limp ≠Nil Alors Prec_imp ^.Suiv←Nil Fsi ;
Fin ;
EXERCICE 6 :
Soit FENT un fichier d’entiers.
1- Ecrire une action paramétrée FLISTE permettant de créer une liste chainée L contenant les éléments de FENT dans le
même ordre (en FIFO).
2- Soit VAL une valeur entière donnée. Ecrire une action paramétrée permettant de créer une liste POSVAL contenant
toutes les positions de la valeur VAL dans la liste L (en LIFO).
3- Soit K un entier positif. Ecrire une action paramétrée DELPOS permettant de supprimer l’élément se trouvant à la Keme
position de la liste L.

Type FichEnt:fichier de enteir;


Fonction Fliste(Fent : FichEnt):pList
Var
L, p, prcd : pList;
v : Entier;
Debut
L ← Nil;
Relire(Fent);
Si (NoN(FDF(Fent))) Alors
Lire(Fent, v);
Allouer(L);
L^.val ←v;
prcd ← L;
Tant Que (NoN(FDF(Fent))) Faire
Lire(Fent, v);
Allouer(p);
p^.val ← v;
prcd^.svt ← p;
prcd ← p;
Fait
prcd^.svt ← Nil;
Fsi
Fermer(Fent);
Retourner L;
Fin;

19
2- Soit VAL une valeur entière donnée. Ecrire une action paramétrée permettant de créer une liste POSVAL contenant
toutes les positions de la valeur VAL dans la liste L (en LIFO).

Fonction PosVal(L: pList, Val:Entier):pList


Var
p, Lval: pList;
pos : Entier;
Debut
Lval ← Nil;
pos ← 0;
Tant Que (L <> Nil) Faire
pos ← pos + 1;
Si (L^.val = Val) alors
Allouer(p);
p^.val ← pos;
p^.svt ← Lval;
Lval ← p;
Fsi
L ← L^.svt;
Fait
Retourner Lval;
Fin;
3- Soit K un entier positif. Ecrire une action paramétrée DELPOS permettant de supprimer l’élément se trouvant à la
Keme position de la liste L

Fonction DelPos(L:pList, K:Entier):pList


Var
Var P,Q : Pliste;
Debut

Si L ≠ Nil
Alors
Si K>=1
Alors
Si K = 1 Alors P← L ^.Suiv ; Liberer(L); L ← P //suppression de la tete
Sinon // chercher dans Q le précédent du kieme élément et P pointe l'élement K
P ← L;
Tantque P ≠ Nil Et K>1
Faire Q ← P; P ← P^.Suiv; K ← K – 1; Fait;
Si P ≠ Nil
Q^.Suiv ← P^.Suiv ;
Liberer(P) //milieu ou à la fin
Fsi;
Fsi
Fsi;
Fsi;
retourner L;
20
Fin;

21

Vous aimerez peut-être aussi