ALGORITHMIQUE ET STRUCTURE DE DONNEES
Corrigé TD5 TIC-1
Les listes chaînées
Enseignante : Hajer SALHI
Exercice 1
On se propose d’effectuer des opérations sur une liste chaînée formée par des entiers distincts (sans
répétitions).
1 Définir la structure LISTE_INT représentant une telle liste.
Nœud = Enregistrement
Val : entier
suiv : ^ Nœud
Fin Enreg
LISTE_INT = ^ Noeud
2 Ecrire la fonction appartient(x, L) qui teste si un entier x donné appartient ou non á une liste L.
Fonction appartient (x : entier, L : LISTE_INT) : booléen // Version Itérative
Variables p : LISTE_INT
Début
pL
Tant que (p <> NIL) et (p^.Val <> x) faire
p p^.suiv
Fin Tantque
Si (p <> NIL) alors
appartient vrai
Sinon ou bien appartient (p <> NIL)
appartient faux
Fin Si
FIN
Fonction appartient (x : entier, L : LISTE_INT) : booléen // Version Récursive
Variables
Début
Si (L <> NIL) et (L^.Val <> x) alors
appartient appartient (x, L^.suiv)
Sinon
appartient (L <> NIL)
Fin Si
FIN
1
3 Ecrire la procédure insère(x, L, ok) qui permet d’insérer x dans la liste définie par L. Si x se trouve
déjà dans la liste L, l’insertion est refusée et la variable booléenne ok prend la valeur faux. Sinon, x
sera inséré dans la liste et t la variable ok prend la valeur vrai.
Procedure insere (x : entier, var L : LISTE_INT, Ok : booléen) // Insertion au début
Variables p : LISTE_INT
Début
Si (appartient(x,L) = vrai) alors
Ok faux
Sinon
OK vrai
Créer (p)
p^.Val x
p^.suiv L
L p
Fin Si
FIN
Procedure insere (x : entier, var L : LISTE_INT, Ok : booléen) // Insertion à la fin
Variables p, q : LISTE_INT
Début
Si (appartient(x,L) = vrai) alors
Ok faux
Sinon
OK vrai
Créer (p)
p^.Val x
p^.suiv NIL
Si (L = NIL) alors
Lp
Sinon
qL
Tantque (q^.suiv <> NIL) faire
q q^.suiv
Fin tantque
q^.suiv p
Fin Si
Fin Si
FIN
4 Ecrire la procédure récursive insère_liste(L1, L2) qui permet d’insérer tous les éléments de la liste
L1 dans la liste L2.
Remarque : Les éléments de L1 ne seront insérés dans L2 que s’ils n’y existent pas déjà.
Procedure insere_Liste (L1 : LISTE_INT, var L2 : LISTE_INT)
Variables p : LISTE_INT
R : booléen
Début
Si (L1<> NIL) alors
Insere (L1^.val, L2, R)
Insere_Liste (L1^.suiv, L2)
Fin Si
FIN
2
5 Ecrire la fonction récursive commun(L1, L2) qui retourne vrai si les deux listes définies par L1 et
L2 ont au moins un élément en commun et faux sinon.
Fonction commun (L1, L2 : LISTE_INT) : booléen
Variables p : LISTE_INT
R : booléen
Début
Si (L1 <> NIL) alors
Si ( (appartient (L1^.val, L2) )
commun vrai
Sinon
commun commun (L1^.suiv, L2)
Sinon
Commun faux
Fin Si
FIN
3
Exercice 2 ( En utilisant une liste chainée simple)
1.- Soit L une liste chainée d´entiers initialement vide.
Écrire la procédure CHARGER_LISTE1 qui accepte une suite d´entiers différents de -1 et les chargent dans
la liste chaînée L dans l´ordre inverse de leur introduction.
Exemple:
Si l´utilisateur saisit les valeurs : 2, 34, 55, -1 alors la liste L résultante contient : 55 34 2
Version de l’ordre des entiers ➔ Insertion au début
Procédure CHARGER_LISTE1 (var L : LISTE_INT) // version itérative
Variables p : LISTE_INT
Début
Ecrire (‘‘Donner la liste d’entiers se terminant par -1’’)
Lire (x)
Tant que ( x <> −1) ) faire
Créer (p)
p^.Val x
p^.suiv L
L p
Lire (x)
Fin tantque
FIN
Procédure CHARGER_LISTE1 (var L : LISTE_INT) // version récursive
Variables p : LISTE_INT
Début
Ecrire (‘‘Donner la liste d’entiers se terminant par -1’’)
Lire (x)
Si ( x <> −1) ) alors
Créer (p)
p^.Val x
p^.suiv L
L p
CHARGER_LISTE1(L^.suiv)
Fin Si
FIN
4
2.- Soit L une liste chainée d´entiers initialement vide.
Écrire la procédure CHARGER_LISTE2 qui accepte une suite d´entiers différents de -1 et les chargent dans
la liste chaînée L dans le même ordre de leur introduction.
Exemple:
Si l´utilisateur saisit les valeurs : 2, 34, 55, -1 alors la liste L résultante contient : 2 34 55
Garder l’ordre des entiers ➔ Insertion à la fin
Procédure CHARGER_LISTE2 (var L : LISTE_INT) // version itérative
Variables p, q : LISTE_INT
Début
Ecrire (‘‘Donner la liste d’entiers se terminant par -1’’)
Lire (x)
Si (x <> -1) alors // insertion du premier élément de la liste chainée
Créer (p)
p^.Val x
p^.suiv NIL
Lp
qL
Lire (x)
Tant que ( x <> −1) ) faire
Créer (p)
p^.Val x
p^.suiv NIL
q^.suiv p
q q^.suiv
Lire (x)
Fin tantque
Fin Si
FIN
Procédure CHARGER_LISTE2 (var L, q : LISTE_INT) // version récursive
Variables p : LISTE_INT
Début
Ecrire (‘‘Donner la liste d’entiers se terminant par -1’’)
Lire (x)
Si (x <>-1) alors
Créer (p)
p^.Val x
p^.suiv NIL
Si ( L = NIL ) alors // insertion du premier élément de la liste chainée
Lp
qL
Sinon
q^.suiv p
q q^.suiv
Fin Si
CHARGER_LISTE2 (L, q)
Fin Si
FIN
5
3. Ecrire une procédure Afficher(L) qui affiche les éléments d´une liste d´entiers L.
Procédure Afficher ( L : LISTE_INT) // version itérative
Variables p : LISTE_INT
Début
pL
Tant que (p <> NIL) alors
Ecrire (p^.Val)
p p^.suiv
Fin Si
FIN
Procédure Afficher ( L : LISTE_INT) // version récursive
Variables
Début
Si (L <> NIL) alors
Ecrire (L^.Val)
Afficher (L^.suiv)
Fin Si
FIN
4. Ecrire un algorithme qui accepte une suite d´entiers différents de -1 et les charge dans une liste d´entiers
L dans l´ordre inverse de leur introduction.
Algorithme charge_Liste_entiers
Variables L : LISTE_INT
Début
L NIL
CHARGER_LISTE1 (L)
FIN
Ecrire un algorithme qui accepte une suite d´entiers différents de -1 et les charge dans une liste d´entiers L
dans le même ordre de leur introduction.
Algorithme charge_Liste_entiers // Si on veut utiliser la version itérative
Variables L : LISTE_INT
Début
L NIL
CHARGER_LISTE2 (L)
FIN
Algorithme charge_Liste_entiers // Si on veut utiliser la version récursive
Variables L, q : LISTE_INT
Début
L NIL
q NIL
CHARGER_LISTE2 (L, q)
FIN
6
Exercice 3
1. Ecrire une fonction qui permet de trouver la première occurrence d’un entier x dans une liste chainée
d’entiers.
Fonction Prem_Occ (x : entier, L : LISTE_INT) : LISTE_INT
Variables
Début
Si (L <> NIL) et (L^.Val <> x) alors
Prem_Occ Prem_Occ (x, L^.suiv)
Sinon si (L^.Val = x) alors
Prem_Occ L
Sinon
Prem_Occ NIL
Fin Si
FIN
2. Ecrire une procédure qui permet de supprimer la première occurrence d’un entier x dans une liste chainée
d’entiers.
Procedure Supp_Prem_Occ (x : entier, var L : LISTE_INT)
Variables p, q, pred : LISTE_INT
Début
p = Prem_Occ (x, L)
Si ( (p <> NIL) alors // la valeur de x existe dans la liste
Si p = L alors // p est en tète de liste
L L^.suiv
Sinon // p n’est pas en tète de liste
pred L
Tant que (pred^.suiv <> p) faire // détermination du pred de p
pred pred^.suiv
Fin Tantque
pred^.suiv p^.suiv
Fin Si
Libérer (p)
Fin Si
FIN
3. Ecrire une procédure qui permet de supprimer toutes les occurrences d’un entier x dans une liste chainée
d’entiers.
Procedure Supp_All_Occ (x : entier, var L : LISTE_INT) // version itérative
Variables p, q, pred : LISTE_INT
Début
p Prem_Occ (x, L)
Tantque ( p <> NIL) faire // la valeur de x existe dans la liste
Supp_Prem_Occ (x, L)
p Prem_Occ (x, L)
Fin Tantque
FIN
7
Procedure Supp_All_Occ (x : entier, var L : LISTE_INT)// version itérative (autre version)
Variables p, q, pred : LISTE_INT
Début
p Prem_Occ (x, L)
Tantque ( (p <> NIL) faire // la valeur de x existe dans la liste
Si p = L alors // p est en tète de liste
L L^.suiv
q L
Sinon // p n’est pas en tète de liste
pred L
Tant que (pred^.suiv <> p) faire // détermination du pred de p
pred pred^.suiv
Fin Tantque
pred^.suiv p^.suiv
q pred^.suiv
Fin Si
Libérer (p)
p Prem_Occ (x, q) // On termine la recherche à partir de ce pointeur
Fin Tantque
FIN
Procedure Supp_All_Occ (x : entier, var L : LISTE_INT) // version récursive
Variables p, q, pred : LISTE_INT
Début
p Prem_Occ (x, L)
Si ( p <> NIL) alors // la valeur de x existe dans la liste
Supp_Prem_Occ (x, L)
Supp_All_Occ (x, L)
Fin Si
FIN
Procedure Supp_All_Occ (x : entier, var L : LISTE_INT) //version récursive(autre version)
Variables p, q, pred : LISTE_INT
Début
p Prem_Occ (x, L)
Si ( (p <> NIL) alors // la valeur de x existe dans la liste
Si p = L alors // p est en tète de liste
L L^.suiv
Sinon // p n’est pas en tète de liste
pred L
Tant que (q^.suiv ≠ p) faire // détermination du pred de p
pred pred^.suiv
Fin Tantque
pred^.suiv p^.suiv
Fin Si
Libérer (p)
8
Supp_All_Occ (x, L)
Fin Si
FIN
Procedure Supp_All_Occ (x : entier, var L : LISTE_INT)// Amélioration version Itérative
// Un seul Parcours
Variables p, q, pred : LISTE_INT
Début
p L ; pred NIL
Tantque ( (p <> NIL) faire
Tantque ( (p <> NIL et p^.val <> x) faire
pred p
p p^.suiv
Fin Tantque
Si ( p <> NIL) alors // la valeur x existe dans la chaine
Si p = L alors // p est en tête de liste
L L^.suiv
pL
Sinon // p n’est pas en tête de liste
pred^.suiv p^.suiv
Fin Si
Libérer (p)
p pred^.suiv // On termine la recherche à partir de ce pointeur
Fin Si
Fin Tantque
FIN