Vous êtes sur la page 1sur 278

Algorithmique et structures de données

Chapitre 1

Les éléments de base des


algorithmes

Exercice 1.1
Définir le vocable variable.

Une variable est un emplacement nommé de la mémoire centrale de l’ordinateur


dans lequel on peut stocker une valeur.

Exercice 1.2
Choisir des identificateurs expressifs et écrire des instructions de déclaration
pour déclarer les variables suivantes :
(a) Prix de vente (b) Nombre de pages d’un livre
(c) Moyenne des notes (d) Age en années
(e) Lieu de naissance (f) Salaire net
(g) Note de contrôle continue (h) Date de naissance
(i) Numéro matricule (j) Nature du baccalauréat
(k) Année d’obtention du baccalauréat (m) Mention obtenue au baccalauréat

(a) var (b) var


PrixVente : réel ; NombrePages : entier ;
(c) var (d) var
Moyenne : réel ; Age : entier ;
(e) var (f) var
LieuNaissance : chaîné ; SalaireNet : réel ;
(g) var (h) var
ContrôleContinu : entier ; DateNaissance : chaîne ;
(i) var (j) var
Matricule : chaîne ; NatureBac : chaîne ;
(k) var (m) var
AnnéeBac : entier ; MentionBac : chaîne ;

Exercice 1.3
Écrire un algorithme qui lit six nombres réels A, B, C, D, E et F et calcule la
solution du système d’équations

1
Dr Ndi Nyoungui André
Algorithmique et structures de données

Ax + By = C
Dx + Ey = F

en supposant que le système admet une solution unique (déterminant non nul).

On utilise la méthode de Cramer pour la résolution des systèmes d’équations


linéaires. Si on suppose que le système a une solution unique, la méthode Cramer
établit que la solution du système est donnée par :

C*E−C*F
x=
A*E−B*D

A*F−C*D
y=
A*E−B*D

L’algorithme est alors le suivant :


Algorithme Système ;
variable
A, B, C, D, E, F, x, y, detx, dety, det : réel ;
début
écrire('Quelle est la valeur de A ? ') ;
lire(A) ;
écrire('Quelle est la valeur de B ? ') ;
lire(B) ;
écrire('Quelle est la valeur de C ? ') ;
lire(C) ;
écrire('Quelle est la valeur de D ? ') ;
lire(D) ;
écrire('Quelle est la valeur de E ? ') ;
lire(E) ;
écrire('Quelle est la valeur de F ? ') ;
lire(F) ;

{Calcul des déterminants}


det ← A*E – D*B ;
detx ← C*E – B*F ;
dety ← A*F – D*C;

{Calcul de la solution}
x ← detx/det;
y ← dety/det;

{Impression des résultats}

2
Dr Ndi Nyoungui André
Algorithmique et structures de données

écrire('x = ', x);


écrire('y = ', y) ;
fin ;

Exercice 1.4
Écrire un algorithme pour lire deux nombres réels A et B (A différent de zéro)
puis calculer la solution de l’équation Ax + B = 0.

On utilise la méthode de résolution des équations du premier degré pures qui se


présente de la manière suivante : la solution de l’équation Ax + B = 0, A ≠ 0, est
x = -B/A.

L’algorithme est alors le suivant.


Algorithme Équation ;
variable
A, B, x : réel ;
début
écrire('Quelle est la valeur de A ? ') ;
lire(A) ;
écrire('Quelle est la valeur de B ? ') ;
lire(B) ;

{Calcul de la solution}
x ← -B/A;

{Impression du résultat}
écrire('x = ', x);
fin ;

Exercice 1.5
Écrire un algorithme qui lit le rayon d’une sphère, calcule et affiche le volume de
la sphère.

L’algorithme est le suivant :


Algorithme Sphère ;
constante
pi = 3.14159 ;
variable
Rayon, Volume : réel ;
début
écrire('Quelle est la valeur rayon ? ') ;
lire(Rayon) ;

3
Dr Ndi Nyoungui André
Algorithmique et structures de données

{Calcul de la solution}
Volume ← (4/3)*pi*Rayon*Rayon*Rayon;

{Impression du résultat}
écrire('Rayon : ', Rayon) ;
écrire('Volume : ', Volume);
fin ;

Exercice 1.6
Écrire un algorithme qui calcule et affiche la longueur de l’hypoténuse d’un
triangle rectangle connaissant les longueurs des côtés perpendiculaires.

L’algorithme est le suivant :


Algorithme Rectangle ;
variable
Côté1, Côté2, Hypoténuse : réel ;
début
écrire('Longueur du premier côté : ' ‘) ;
lire(Côté1) ;
écrire('Longueur du dexième côté : ') ;
lire(Côté2) ;

{Calcul de la solution}
Hypoténuse ← sqrt(sqr(Côtés1) + sqr(Côté2));

{Impression du résultat}
écrireln('Premier côté : ', Coôté1) ;
écrireln('Deuxième côté : ', Côté2) ;
écrireln('Hypoténuse : ', Hypoténuse);
fin ;

Exercice 1.7
Écrire un algorithme qui lit la longueur et la largeur d’un rectangle, calcule et
affiche le périmètre et la surface du rectangle.

L’algorithme est le suivant :


Algorithme Sphère ;
variable
Longueur, Largeur, Périmètre, Surface : réel ;
début
écrire('Quelle est la longueur ? ') ;
lire(Longueur) ;
écrire('Quelle est la largeur ? ') ;

4
Dr Ndi Nyoungui André
Algorithmique et structures de données

lire(Largeur) ;

{Calcul de la solution}
Périmètre ← 2*(Largeur + Longueur) ;
Surface ← Largeur*Longueur ;

{Impression des résultats}


écrireln('Largeur : ', Largeur) ;
écrirlen('Longueur : ', Longueur) ;
écrireln('Périmètre : ', Périmètre);
écrireln('Surface : ', Surface) ;
fin ;

Exercice 1.8
Écrire un algorithme qui lit le nom et le prénom d’un employé, le nombre d’heures
de travail qu’il a effectuées et son taux horaire puis calcule et affiche, le nom, le
prénom et le salaire de l’employé.

L’algorithme est le suivant :


Algorithme Sphère ;
variable
Nom, Prénom : chaîne ;
Heures, Taux, Salaire : réel ;
début
écrire('Nom : ') ;
lire(Nom) ;
écrire('Prénom : ') ;
lire(Prénom) ;
écrire('Heures effectuées : ') ; '
lire(Heures) ;
écrire('Taux horaire : ') ;
lire(Taux) ;

{Calcul du salaire}
Salaire ← Taux*Heures ;

{Impression des résultats}


écrireln('Nom : ', Nom) ;
écrireln('Prénom : ', Prénom) ;
écrireln('Salaire : ', Salaire) ;
fin ;

Exercice 1.9

5
Dr Ndi Nyoungui André
Algorithmique et structures de données

Écrire un algorithme qui lit la note de contrôle continu et la note de synthèse


d’un étudiant dans une certaine unité de valeur puis calcule la moyenne de
l’étudiant dans cette unité de valeur sachant que le contrôle continu compte pour
30% et la note de synthèse pour 70%.

L’algorithme est le suivant :


Algorithme Notes ;
variable
Contrôle, Synthèse, Moyenne : réel ;
début
écrire('Entrez la note de contrôle continu : ') ;
lire(Contrôle) ;
écrire('Entrez la note de synthèse : ') ;
lire(Synthèse) ;

{Calcul de la moyenne}
Moyenne ← 0.3*Contrôle + 0.7*Synthèse ;

{Impression de la moyenne}
écrire('Contrôle continu : ', Contrôle) ;
écrire('Synthèse : ', Synthèse) ;
écrire('Moyenne : ', Moyenne)
fin ;

Exercice 1.10
Écrire un algorithme qui convertit les degrés Fahrenheit (F) en degrés Kelvin (K)
en utilisant la relation K = (5/9)(F – 32) + 273.

L’algorithme est le suivant :


Algorithme Conversion ;
variable
K, F : réel ;
Début
écrire('Quel est le nombre de degrés Fahrenheit à convertir ? ')
lire(F) ;

{Conversion}
K ← (5/9)*(F – 32) + 273 ;

{Impression du résultat}
écrire(F, 'degrés F = ', K, 'degrés K') ;
fin ;

6
Dr Ndi Nyoungui André
Algorithmique et structures de données

Exercice 1.11
Écrire un algorithme qui un montant exprimé en francs CFA puis calcule et
imprime ses équivalents en euros et en dollars américains.

L’algorithme est le suivant :


Algorithme Change ;
variable
TauxEuros = ;
TauxDollars = ;
variable
Montant, Euros, Dollars : réel ;
début
écrire('Quel est le montant à convertir ? ') ;
Lire(Montant) ;

{Calcul du résultat}
Euros ← TauxEuros*Montant ;
Dollars ← TauxDollars*Montant ;

{Impression des résultats}


Écrire(Montant, 'FCFA = ', Euros, 'Euros') ;
Écrire(Montant, 'FCFA = ', Dollars, 'Dollars US') ;
fin ;

Exercice 1.12
Une compagnie a quatre divisions qui vendent une variété de produits. La
direction de la compagnie veut connaître quel pourcentage des ventes totales est
généré par chaque division. Écrire un algorithme qui lit le montant des ventes
générées par chaque division et imprime le montant total des ventes ainsi que le
pourcentage des ventes de chacune des divisions.

L’algorithme est le suivant :


Algorithme Gestion ;
variable
Ventes1, Ventes2, Ventes3, Ventes4, Ventes5 : réel ;
p1, p2, p3, p4, total : réel ;
début
écrire('Quel est le montant des ventes de la division 1 ? ')
lire(Ventes1) ;
écrire('Quel est le montant des ventes de la division 2 ? ')
lire(Ventes2) ;
écrire('Quel est le montant des ventes de la division 3 ? ')

7
Dr Ndi Nyoungui André
Algorithmique et structures de données

lire(Ventes3) ;
écrire('Quel est le montant des ventes de la division 4 ? ')
lire(Ventes4) ;

{Calcul des résultats}


Total ← Ventes1 + Ventes2 + Ventes3 + Ventes4 ;
p1 ← 100*(Ventes1/Total) ;
p2 ← 100*(Ventes2/Total) ;
p3 ← 100*(Ventes3/Total) ;
p4 ← 100*(Ventes4/Total) ;

{Impression des résultats}


Écrire('Ventes totales : ', Total) ;
Écrire('Division 1 : ', p1, ‘%’) ;
Écrire('Division 2 : ', p2, ‘%’) ;
Écrire('Division 3 : ', p3, ‘%’) ;
Écrire('Division 4 : ', p4, ‘%’) ;
fin ;

8
Dr Ndi Nyoungui André
Algorithmique et structures de données

Chapitre 2

La sélection

Exercice 2.1
Si une expression booléenne utilise des opérateurs logiques tels que ET et OU,
ainsi que des opérateurs relationnels, pourquoi doit on utiliser des parenthèses ?

Réponse

Les expressions logiques utilisant les opérateurs OU et ET doivent utiliser les


parenthèses à cause de la priorité de ces opérateurs.

Exercice 2.2
Lesquelles des expressions booléennes suivantes sont logiquement équivalentes ?
p et q sont deux variables booléennes.
(a) p ≠ q (b) (p et non q) ou (non p et q)
(c) non(p = q) (d) (p ou q) ou non(p et q)

Réponse

Les expressions équivalences logiquement sont a, b et c.

Exercice 2.3
Réécrire chacune des instructions suivantes sans utiliser des conditions
composées.

(a)
si (x < y) ou (w < z) alors
Écrire('Bonjour')
sinon
Écrire('Bonsoir') ;

(b)
si ((a ≥ b) ou (c = 5)) et (d = 1) alors
Écrire('Bonjour')
sinon
Écrire('Bonsoir') ;
9
Dr Ndi Nyoungui André
Algorithmique et structures de données

(c)
si ((a ≥ b) et (c = 5)) ou (d = 1) alors
Écrire('Bonjour')
sinon
Écrire('Bonsoir') ;

(d)
si ((a ≥ b) et (c = 5)) et (d = 1) alors
Écrire('Bonjour')
sinon
Écrire('Bonsoir') ;

Réponse

(a)
si x < y alors
Écrire('Bonjour')
sinon
si w < z alors
Écrire('Bonjour')
sinon
Écrire('Bonsoir') ;

(b)
si a ≥ b alors
si d = 1 alors
Écrire('Bonjour')
sinon
Écrire('Bonsoir')
sinon
si c = 5 alors
si d = 1 alors
Écrire('Bonjour')
sinon
Écrire('Bonsoir') ;

(c)
si a ≥ b alors
si c = 5 alors
Écrire('Bonjour')
sinon
si d = 1 alors

10
Dr Ndi Nyoungui André
Algorithmique et structures de données

Écrire('Bonjour')
sinon
Écrire('Bonjour') ;

(d)
si a ≥ b alors
si c = 5 alors
si d = 1 alors
Écrire('Bonjour')
sinon
sinon
sinon
Écrire('Bonsoir') ;

Exercice 2.4
Les longueurs des côtés d’un triangle sont stockées dans les variables réelles a, b
et c. Pour que a, b et c soient effectivement correctes, la somme de deux
quelconque des trois nombres doit être strictement supérieure au troisième.
Écrire un algorithme qui lit trois nombres réels a, b et c et détermine si a, b et c
sont effectivement les côtés d’un triangle. Si oui, alors écrire le message « Les
nombres forment un triangle » dans le cas contraire écrire le message « Les
nombres de forment pas un triangle ».

L’algorithme est le suivant :


Algorithme Triangle ;
variable
a, b, c : réel ;
début
écrire('Entrez les valeurs de a, b et c') ;
lire(a, b, c) ;

si ((a + b) > c ) ou ((a + c) > b) ou ((b + c) > a) alors


écrire('Les nombres forment un triangle')
sinon
écrire('Les nombres ne forment pas un triangle')
fin.

Exercice 2.5
Une année est bissextile si son millésime est un multiple de 4, sauf les années de
début de siècle qui sont bissextiles si leur millésime est divisible par 400. Écrire
un algorithme qui lit un entier naturel et détermine si cet entier représente une
année bissextile.

11
Dr Ndi Nyoungui André
Algorithmique et structures de données

Première version

Algorithme Bissextile ;
variable
année : entier ;
début
écrire('Quelle année ? ') ;
lire(année) ;

si (année mod 4) ≠ 0 alors


écrire(année, 'pas une année bissextile')
sinon
si ((année mod 100) = 0) et ((année mod 400) ≠ 0) alors
écrire(année, 'pas une année bissextile')
sinon
écrire(année, 'est une année bissextile') ;
fin.

Deuxième version

Algorithme Bissextile ;.
variable
année : entier ;
début
écrire('Quelle année ? ') ;
lire(année) ;

si ((année mod 4) = 0) et (((année mod 100) ≠ 0) ou ((année mod 400) = 0))


alors
écrire(année, 'est une année bissextile')
sinon
écrire(année, 'pas une année bissextile') ;
fin.

Exercice 2.6
Une boulangerie est ouverte de 7 heures à 13 heures et de 16 heures à 19
heures, sauf le dimanche après-midi et le lundi toute la journée. Écrire un
algorithme qui lit une heure (un entier naturel) et un jour (une chaîne de
caractère) et détermine si la boulangerie est ouverte le jour et à l’heure
indiqués.

12
Dr Ndi Nyoungui André
Algorithmique et structures de données

L’algorithme est le suivant :


Algorithme Boulangerie;
variable
heure : entier ;
jour : chaîne ;
début
Écrire('Quelle est heure ? ') ;
lire(heure) ;
Écrire('Quel jour de la semaine ? ') ;
lire(jour) ;
si jour = 'lundi' alors
écrire('Boulangerie fermée')
sinon
si jour = 'dimanche' alors
si (heure < 7) ou (heure > 13) alors
écrire('Boulangerie fermée')
sinon
écrire('Boulangerie ouverte')
sinon
si (heure < 7) ou ((heure > 13) et (heure < 16)) ou (heure > 19)
alors
écrire('Boulangerie fermée')
sinon
écrire('Boulangerie ouverte') ;
fin.

Exercice 2.7
Un entier positif est stocké dans une variable nombre. Utiliser une instruction
de sélection multiple pour imprimer un message indiquant si le nombre est paire
ou impaire.

L’algorithme est le suivant :


Algorithme Parité ;
variable
nombre : entier ;
début
écrire('Entrez un nombre') ;
lire(nombre) ;
si nombre < 0 alors
Écrire('Mauvaise donnée')
sinon

13
Dr Ndi Nyoungui André
Algorithmique et structures de données

sélection (nombre mod 2) de


0 : écrire('Nombre paire')
1 : écrire('Nombre impaire') ;
fin ;
fin.

Exercice 2.8
Écrire un programme pour résoudre le système d’équations linéaires d’inconnues
x et y :

Ax + By = C
Dx + Ey = F

On utilise la méthode de Cramer pour la résolution des systèmes d’équations


linéaires.

L’algorithme est le suivant :


Algorithme Système ;
variable
A, B, C, D, E, F, x, y, DETX, DETY, DET : réel ;
début
écrire(' Entrez les coefficients A, B, C, D, E, F') ;
lire(A, B, C, D, E, F) ;

{Calcul des déterminants}


DET ← A*E – D*B ;
DETX ← C*E – B*F ;
DETY ← A*F – D*C;

{Calcul de la solution}
si det ≠ 0 alors
début
x ← DETX/DET;
y ← DETY/DET;
écrire(‘x = ‘, x);
écrire('y = ', y) ;
fin
sinon
si (DETX = 0) et (DETY = 0) alors
écrire('Système indéterminé')
sinon
écrire('Système impossible') ;
fin ;

14
Dr Ndi Nyoungui André
Algorithmique et structures de données

Exercice 2.9
Écrire un algorithme qui lit un nombre représentant l’âge d’une personne et
affiche le message « vous êtes mineur » si son âge est inférieur à 18 ans et le
message « vous êtes majeur » dans le cas contraire.

L’algorithme est le suivant :


Algorithme Majeur ;
variable
âge : entier ;
début
écrire('Quel est votre âge ? ') ;
lire(âge) ;
si âge < 18 alors
écrire('Vous êtes mineur')
sinon
écrire('Vous êtes majeur') ;
fin.

Exercice 2.10
Écrire un algorithme qui lit le nom et le sexe d’une personne et affiche le
message « Bonjour, Monsieur … » si la personne est de sexe masculin et le
message « Bonjour, Madame … » si la personne est de sexe féminin.

L’algorithme est le suivant :


Algorithme Salutation ;
variable
nom: chaîne ;
sexe : caractère ;
début
écrire('Quel est votre nom ? ') ;
lire(nom) ;
écrire('Quel est votre sexe (M ou F) ? ') ;
lire(sexe) ;
si sexe = ‘M’ alors
écrire('Bonjour monsieur ', nom)
sinon
écrire('Bonjour madame ', nom) ;
fin.

Exercice 2.11

15
Dr Ndi Nyoungui André
Algorithmique et structures de données

Écrire un algorithme qui le nom, le sexe et le statut matrimonial d’une personne


et affiche le message « Bonjour monsieur … » si la personne est de sexe
masculin, le message « Bonjour mademoiselle … » si la personne est une
demoiselle et le message « Bonjour madame … » si la personne est une dame.

L’algorithme est le suivant :


Algorithme Salutation2 ;
variable
nom : chaîne ;
sexe, marié : caractère ;
début
écrire('Quel est votre nom ? ') ;
lire(nom) ;
écrire('Quel est votre sexe (M ou F) ? ') ;
lire(sexe) ;
écrire('Êtes-vous marié (O ou N) ? ') ;
lire(marié) ;
si sexe = 'M' alors
écrire('Bonjour monsieur ', nom)
sinon
si marié = 'O' alors
écrire(' Bonjour madame ', nom)
sinon
écrire('Bonjour mademoiselle ', nom) ;
fin.

Exercice 2.12
Écrire un algorithme qui lit trois nombres et imprime le plus grand des trois
nombres.

Première version

Algorithme max3;
variable
a, b, c : réel ;
début
écrire('Entrez les trois nombres') ;
lire(a, b, c) ;
si a > b alors
si a > c alors
écrire('Le plus grand est : ', a)

16
Dr Ndi Nyoungui André
Algorithmique et structures de données

sinon
écrire('Le plus grand est : ', c)
sinon
si b > c alors
écrire('Le plus grand est : ', b)
sinon
écrire('Le plus grand est : ', c) ;
fin.

Deuxième version

On peut éviter d’utiliser une imbrication très profonde des instructions si…alors
… sinon en utilisant une succession d‘instruction si…alors. L’algorithme devient
alors.

Algorithme max3;
variable
grand, a, b, c: réel ;
début
écrire('Entrez les trois nombres') ;
lire(a, b, c) ;
grand ← a ;
si b > grand alors
grand ← b ;
si c > grand alors
grand ← c ;

écrire('Le plus grand est : ', grand) ;


fin.

Troisième solution

On utilise les conditions composées. L’algorithme devient alors.

Algorithme max3;
variable
grand, a, b, c: réel ;
début
écrire('Entrez les trois nombres') ;
lire(a, b, c) ;
si (a ≥ b) et (a ≥ c) alors
écrire('Le plus grand est : ', a) ;
17
Dr Ndi Nyoungui André
Algorithmique et structures de données

sinon
si (b ≥ a) et (b ≥ c) alors
écrire('Le plus grand est : ', b) ;
sinon
écrire('Le plus grand est : ', c) ;
fin.

Exercice 2.13
Écrire un algorithme qui lit quatre nombres et imprime le plus grand des quatre
nombres.

Première version, utilisation des instructions si…alors…sinon imbriquées.

L’algorithme est le suivant :


Algorithme Plusgrand4 ;
variable
a, b, c, d : réel ;
début
écrire('Entrez les quatre nombres') ;
lire(a, b, c, d) ;
si a > b alors
si a > c alors
si a > d alors
écrire('Le plus grand est : ', a) ;
sinon
écrire('Le plus grand est : ', d) ;
sinon
si c > d alors
écrire('Le plus grand est : ', c)
sinon
écrire('Le plus grand est : ', d)
sinon
si b > c alors
si b > d alors
écrire('Le plus grand est : ', b)
sinon
écrire('Le plus grand est : ', d)
sinon
si c > d alors
écrire('Le plus grand est : ', c)
sinon

18
Dr Ndi Nyoungui André
Algorithmique et structures de données

écrire('Le plus grand est : ', d) ;


fin.

Deuxième version, utilisation des instructions si…alors

On peut éviter d’utiliser une imbrication très profonde des instructions si…alors
… sinon en utilisant une succession d‘instruction si…alors. L’algorithme devient
alors.

L’algorithme est le suivant :


Algorithme Plusgrand4;
variable
grand, a, b, c, d : réel ;
début
écrire('Entrez les quatre nombres') ;
lire(a, b, c, d) ;
grand ← a ;
si b > grand alors
grand ← b ;
si c > grand alors
grand ← c ;
si d > grand alors
grand ← d ;

écrire('Le plus grand est : ', grand) ;


fin.

Troisième version, utilisation des conditions composées

On utilise les instructions composées. L’algorithme devient alors.

L’algorithme est le suivant :


Algorithme Plusgrand4;
variable
grand, a, b, c, d : réel ;
début
écrire('Entrez les quatre nombres') ;
lire(a, b, c, d) ;
si (a ≥ b) et (a ≥ c) et (a ≥ d) alors
écrire('Le plus grand est : ', a) ;
sinon
si (b ≥ a) et (b ≥ c) et (b ≥ d) alors
19
Dr Ndi Nyoungui André
Algorithmique et structures de données

écrire('Le plus grand est : ', b) ;


sinon
si (c ≥ a) et (c ≥ b) et (c ≥ d) alors
écrire('Le plus grand est : ', c) ;
sinon
écrire('Le plus grand est : ', d) ;
fin.

Exercice 2.14
Écrire un algorithme qui lit deux nombres réels A et B puis calcule la solution
réelle de l’équation Ax + B = 0.

On utilise la méthode générale de résolution des équations du premier degré qui


se présente de la manière suivante :
• a ≠ 0, le système admet la solution unique x = -B/A
•a=0
•• b = 0, le système admet une infinité de solution
•• b ≠ 0, le système admet zéro solution.

L’algorithme est alors le suivant :


Algorithme Équation ;
variable
a, b, x : réel ;
début
écrire('Entrez les coefficients a et b') ;
lire(a, b) ;
si a ≠ 0 alors
début
x ← –b/a ;
écrire('x = ' , x);
fin
sinon
si b = 0 alors
écrire('Équation indéterminée')
sinon
écrire('Équation impossible') ;
fin.

Exercice 2.15
Écrire un algorithme qui lit trois nombres réels a, b et c puis calcule les solutions
réelles de l’équation quadratique ax bxc=0 .
2

20
Dr Ndi Nyoungui André
Algorithmique et structures de données

On utilise la méthode de résolution des équations du second degré qui se


présente de la manière suivante.
• a ≠ 0 (équation du second degré pure),
•• b*b – 4*a*c < 0, le système admet zéro solution
•• b*b – 4*a*c = 0, le système admet la solution double x = -B/2*A
•• b*b – 4*a*c >0, le système admet deux solutions distinctes

x=−b b∗b− 4∗a∗c /  2∗a 


et
x=−b− b∗b−4∗a∗c /  2∗a 

• a = 0 (équation du premier degré)


•• b ≠ 0, le système admet la solution unique x = -C/B
•• b = 0,
••• c ≠ 0, alors le système admet une infinité de solutions
••• c =0, le système admet zéro solution.

L’algorithme est alors le suivant :


Algorithme Quadratique ;
variable
a, b, c, x1, x2, delta : réel ;
début
écrire('Entrez les coefficients a, b et c') ;
lire(a, b, c) ;
si a ≠ 0 alors {Équation du second degré}
début
delta ← b*b – 4*a*c ;
si detla < 0 alors
écrire('Équation impossible')
sinon
si delta = 0 alors
début
x1 ← –b/(2*a);
écrire('Solution double: ', x1) ;
fin
sinon
début
x1 ← (–b + sqrt(delta))/(2*a);
x2 ← (–b – sqrt(delta))/(2*a);

21
Dr Ndi Nyoungui André
Algorithmique et structures de données

écrire('Deux solutions distinctes: ', x1,


x2) ;
fin
fin
sinon {Équation du premier degré}
si b ≠ 0 alors
début
x1 ← –c/b ;
écrire('Solution unique : ', x1) ;
fin
sinon
si c = 0 alors
écrire('Équation indéterminée')
sinon
écrire('Équation impossible') ;
fin.

Exercice 2.16
Les tarifs d’affranchissement d’une lettre sont les suivants :
en-dessous de 20g : 280 FCFA,
à partir de 20g, mais en-dessous de 50g : 440 FCFA,
à partir de 50g : 670 FCFA.
Écrire un algorithme qui lit le poids d’une lettre et imprime le montant de
l’affranchissement de la lettre.

L’algorithme est le suivant :


Algorithme Poste ;
variable
poids, montant : réel ;
début
écrire('Entrez le poids :') ;
lire(poids) ;
si poids < 20 alors
montant ← 280
sinon
si poids < 50 alors
montant ← 440
sinon
montant ← 670 ;

écrire('Poids de la lettre : ', poids) ;

22
Dr Ndi Nyoungui André
Algorithmique et structures de données

écrire('Montant : ', montant) ;


fin.

Exercice 2.17
La variable réelle Hours contient un nombre compris entre 0 et 100. Écrire un
algorithme qui lit une heure et affiche le message correspondant comme indiqué
ci-dessous.

Hours Message
[0..30] Excessive absence
]30..50] Normal
]50..70] Excessive overtime
]70..100] Crazy

L’algorithme est le suivant :


Algorithme Appréciation ;
variable
Hours : entier ;
début
écrire('Entrez le nombre heures') ;
lire(Hours) ;
si (Hours < 0) ou (Hours > 100) alors
écrire('Mauvaise donnée')
sinon
si Hours ≤ 30 alors
écrire('Excessive absence')
sinon
si Hours ≤ 50 alors
écrire('Normal')
sinon
si Hours ≤ 70 alors
écrire('Excessive overtime')
sinon
écrire('Crazy')
fin.

Exercice 2.18

23
Dr Ndi Nyoungui André
Algorithmique et structures de données

On souhaite calculer le montant des impôts dus par un contribuable en fonction


son revenu imposable et de son nombre de parts fiscales. Les règles de calcul
sont les suivantes :
- le revenu par part fiscale est égale au quotient du revenu imposable par le
nombre de parts fiscales
- l’impôt par part fiscale est calculé selon le barème suivant :
• 0 si le revenu par part fiscale est inférieur à 50 000 F ;
• 10% sur la tranche du revenu par part comprise entre 50 000 F et 100
000 F ;
• 25% sur la tranche du revenu par part comprise entre 100 000 F et
200 000 F
• 50% sur le revenu par part fiscale est qui dépasse 200 000 F
- l’impôt total est égal au nombre de parts fiscales multiplié par l’impôt par
part fiscale

Écrire un algorithme qui lit le revenu imposable et le nombre de parts fiscales


d’un contribuable puis calcule le montant des impôts dus par ce contribuable.

L’algorithme est le suivant :


Algorithme Calculimpôt ;
variable
revimp, nbparts, revpart, impart, impôtdus : réel ;
début
écrire('Entrez le revenu imposables') ;
lire(revimp) ;
écrire('Entrez le nombre de parts fiscales') ;
lire(nbparts) ;
revpart ← revimp/nbparts ;
{Calcul de l’impôt par part fiscale}
si revenu ≤ 50000 alors
impart ← 0
sinon
si revenu ≤ 100000 alors
impart ← (revpart – 50000)*0.1
sinon
si revpart ≤ 200000 alors
impart ← (revpart – 100000)*0.25
sinon
impart ← (revpart – 200000)*0.5
impôtdus ← impart * nbparts ;
écrire('Revenu imposable : ', revimp) ;

24
Dr Ndi Nyoungui André
Algorithmique et structures de données

écrire('Nombre de parts fiscales : ', nbparts) ;


écrire('Montant des impôts : ', impôtdus) ;
fin.

Études de cas

Calcul de l’impôt du par un contribuable

Le problème est d’écrire un algorithme pour calculer le montant des impôts dus
par un contribuable, connaissant son revenu imposable. Pour calculer les impôts,
nous allons utiliser le barème présenté dans le tableau ci-dessous

Revenu imposable Taux des impôts

Inférieur à 25000 F 0F

Supérieur à Mais inférieur à Du montant au-dessus de


25000 F 35000 F 14% 25000 F
35000 F 45000 F 500 F + 16% 35000 F
45000 F 65000 F 750 F + 18% 45000 F
65000 F 85000 F 1500 F + 19% 650000 F
85000 F 105000 F 1750 F + 21% 850000 F
105000 F 125000 F 2500 F + 24% 105000 F
125000 F 175000 F 3000 F + 26% 125000 F

Ceci est un barème allégé pour l’objectif du problème. Il ne sera pas difficile de
le généraliser pour traiter un barème plus complet, c’est-à-dire traiter des
revenus supérieurs à 175000 F.

Une première version de l’algorithme est :

début
Lire le revenu imposable
Calculer le montant des impôts dus
Imprimer le revenu imposable et le montant des impôts dus
fin ;

La première instruction n’a pas besoin d’être détailler davantage. La dernière


instruction a besoin d’une petite élaboration. On ne sera capable d’imprimer les
résultats que si le revenu imposable est inférieur à 175000 F. Nous allons utiliser

25
Dr Ndi Nyoungui André
Algorithmique et structures de données

une variable booléenne, possible, pour déterminer si nous somme capables de


calculer les impôts. La dernière instruction devient alors :

si possible alors
début
écrire('Revenu imposable : ', revenu) ;
écrire('Montant des impôts : ', impôt) ;
fin
sinon
écrire('Revenu trop grand') ;

L’instruction Calculer le montant des impôts dus a besoin d’être élaborée. Elle
nécessite que l’on utilise le barème des impôts pour faire le calcul. Pour faire
cela nous allons déterminer l’intervalle dans lequel se trouve le revenu imposable,
et ensuite utiliser le formule approprié pour calculer l’impôt du. Ceci peut être
fait en utilisant des instructions si…alors...sinon imbriquées. Noter que nous
initialisons la variable booléenne possible à vrai. Si on ne peut pas calculer l’impôt
on la met à faux.

possible ← vrai ;
si revenu ≤ 25000 alors
impôt ← 0
sinon
si revenu ≤ 35000 alors
impôt ← (revenu – 25000)*0.14
sinon
si revenu ≤ 45000 alors
impôt ← 500 + (revenu – 35000)*0.16
sinon
si revenu ≤ 65000 alors
impôt ← 750 + (revenu – 45000)*0.18
sinon
si revenu ≤ 85000 alors
impôt ← 1500 + (revenu – 65000)*0.19
sinon
si revenu ≤ 105000 alors
impôt ← 1750 + (revenu – 85000)*0.21
sinon
si revenu ≤ 125000 alors
impôt ← 2500 + (revenu – 105000)*0.24
sinon

26
Dr Ndi Nyoungui André
Algorithmique et structures de données

si revenu ≤ 175000 alors


impôt ← 3000 + (revenu – 125000)*0.26 ;
sinon
possible ← faux ;

Nous pouvons maintenant mettre tout ensemble pour obtenir l’algorithme


complet.

Algorithme IncomeTax ;
variable
revenu, impôt : réel ;
possible : booléen ;
début
écrire('Entrez le revenu imposable : ') ;
lire(revenu) ;

{Calcul des impôts}


possible ← vrai ;
si revenu ≤ 25000 alors
impôt ← 0
sinon
si revenu ≤ 35000 alors
impôt ← (revenu – 25000)*0.14
sinon
si revenu ≤ 45000 alors
impôt ← 500 + (revenu – 35000)*0.16
sinon
si revenu ≤ 65000 alors
impôt ← 750 + (revenu – 45000)*0.18
sinon
si revenu ≤ 85000 alors
impôt ← 1500 + (revenu – 65000)*0.19
sinon
si revenu ≤ 105000 alors
impôt ← 1750 + (revenu – 85000)*0.21
sinon
si revenu ≤ 125000 alors
impôt ← 2500 + (revenu – 105000)*0.24
sinon
si revenu ≤ 175000 alors
impôt ← 3000 + (revenu – 125000)*0.26 ;
sinon

27
Dr Ndi Nyoungui André
Algorithmique et structures de données

possible ← faux ;
si possible alors
début
écrire('Revenu imposable : ', revenu) ;
écrire('Montant des impôts : ', impôt) ;
fin
sinon
écrire('Revenu trop grand') ;
fin.

Calcul du jour de l’année

On veut écrire un algorithme pour calculer le jour de l’année connaissant le mois,


le jour du mois et l’année. Par exemple, si l’entrée de l’algorithme est :

2 7 1983

la sortie de l’algorithme serait :

2/7/1983 est le jour 38 de 1983.

Une version initiale de l’algorithme est :

début
Entrer le mois, le jour et l’année
Calculer le jour de l’année
Imprimer le jour de l’année
fin.

Pour détailler l’instruction « Calculer le jour de l’année », nous utilisons


l’instruction de sélection multiple pour calculer le jour :

sélection mois de
1 : DayOfYear ← jour ;
2 : DayOfYear ← 31 + jour ;
3 : DayOfYear ← 59 + jour ;
4 : DayOfYear ← 90 + jour ;
5 : DayOfYear ← 121 + jour ;
6 : DayOfYear ← 151 + jour ;
7 : DayOfYear ← 182 + jour ;
8 : DayOfYear ← 212 + jour ;
9 : DayOfYear ← 242 + jour ;

28
Dr Ndi Nyoungui André
Algorithmique et structures de données

10 : DayOfYear ← 273 + jour ;


11 : DayOfYear ← 303 + jour ;
12 : DayOfYear ← 334 + jour ;
fin ;

Cette solution est cependant incomplète. Nous avons omis de prendre en compte
les années bissextiles. Le code suivant doit être ajouté à la suite de l’instruction
des sélection à choix multiple.

si (année mod 4 = 0) alors


si ((année mod 100) ≠ 0) ou ((année mod 400 = 0)) alors
DayOfYear ← DayOfYear +1;

Nous pouvons maintenant mettre tout ensemble pour obtenir l’algorithme


suivant :

Algorithme YearDay ;
variable
jour, mois, année, DayOfYear : entier ;
valide : booléen ;
début
écrire('Entrez jour, mois et année') ;
lire(jour, mois, année) ;
valide ← (mois > 0) et (mois < 13) et (jour > 0) et (jour ≤ 31) et (année >
0) ;
si non valide alors
écrire('Mauvaise donnée. Veuillez corriger')
sinon
début
sélection mois de
1 : DayOfYear ← jour ;
2 : DayOfYear ← 31 + jour ;
3 : DayOfYear ← 59 + jour ;
4 : DayOfYear ← 90 + jour ;
5 : DayOfYear ← 121 + jour ;
6 : DayOfYear ← 151 + jour ;
7 : DayOfYear ← 182 + jour ;
8 : DayOfYear ← 212 + jour ;
9 : DayOfYear ← 242 + jour ;
10 : DayOfYear ← 273 + jour ;
11 : DayOfYear ← 303 + jour ;

29
Dr Ndi Nyoungui André
Algorithmique et structures de données

12 : DayOfYear ← 334 + jour ;


fin ;
{On vérifie si l’année est une année bissextile}
si (année mod 4) = 0) alors
si (année mod 100 ≠ 0) ou (année mod 400 = 0) alors
DayOfYear ← DayOfYear +1;

écrire(jour, '/', mois, '/', année);


écrire(DayOfYear, 'de' , année);
fin
fin.

30
Dr Ndi Nyoungui André
Algorithmique et structures de données

Chapitre 3

La répétition

Exercice 3.1
Écrire pour lire une suite de n nombres réels et calculer la moyenne de ces n
nombres ; le nombre n de nombres devant être lu dans l’algorithme.

L’algorithme est le suivant :


Algorithme Moynneliste ;
variable
nombre, total, moyenne : réel ;
i, n : entier ;
début
écrire('Quel est la valeur de n ? ') ;
lire(n) ;
si n ≤ 0 alors
écrire('La liste est vide')
sinon
début
total ← 0 ;
i←0;
tantque i < n faire
début
écrire('Entrez un nombre : ') ;
lire(nombre) ;
total ← total + nombre ;
i←i+1;
fin ;
moyenne ← total/n ;
écrire('Moyenne : ', moyenne) ;
fin ;
fin.

Exercice 3.2
Écrire un algorithme pour lire une suite de n nombres et détermine le plus grand
de ces n nombres ; le nombre n de nombres devant être lu dans l’algorithme.

31
Dr Ndi Nyoungui André
Algorithmique et structures de données

L’algorithme est le suivant :


Algorithme Plusgrand ;
variable
nombre, grand : entier ;
i, n : entier ;
début
écrire('Quel est la valeur de n : ') ;
lire(n) ;
si n ≤ 1 alors
écrire('La liste est vide')
sinon
début
écrire('Entrez un nombre : ') ;
lire(nombre) ;
grand ← nombre ;
i←0;
tantque (i < n) faire
début
écrire('Entrez un nombre : ') ;
lire(nombre) ;
i←i+1;
si nombre > grand alors
grand ← nombre ;
fin,
écrire('Le plus grand nombre est : ' , grand) ;
fin ;
fin.

Exercice 3.3
Lesquelles des assertions suivantes s’appliquent à la structure faire … tantque
seule ? A la structure tantque … faire seule ? Aux deux à la fois ?
(a) le corps de la boucle est exécuté au moins une fois.
(b) l’expression logique qui contrôle la boucle est évaluée avant l’entrée de la
boucle.
(c) doit utiliser la construction début … fin si plusieurs instructions doivent
être répétées.
(d) le corps de la boucle peut ne pas être exécuté du tout.
(e) a une condition de terminaison.
(f) a une condition de répétition.

32
Dr Ndi Nyoungui André
Algorithmique et structures de données

Réponse
instruction
faire … tantque tantque …faire
(a) X
(b) X
(c) X X
(d) X
(e) X
(f) X

Exercice 3.4
Écrire un algorithme qui lit le nom et le sexe d’une personne et affiche le
message « Bonjour, Monsieur … » si la personne est de sexe masculin. Si la
personne est de sexe féminin, le programme lui demande si elle est mariée ou
non. Si la personne est mariée, le programme affiche le message « Bonjour,
madame … » sinon il affiche le message « Bonjour, Mademoiselle … ».

L’algorithme est le suivant :


Algorithme Salutation ;
variable
nom : chaîne ;
sexe, marié : caractère ;
début
écrire('Quel est votre nom ?') ;
lire(nom) ;
écrire('Quel est votre sexe (M ou F) ?') ;
lire(sexe) ;
si sexe = 'M' alors
Écrire('Bonjour monsieur', nom)
sinon
début
écrire('Êtes-vous marié (O ou N) ?') ;
lire(marié) ;

si marié = 'O' alors


écrire('Bonjour madame', nom)
sinon
écrire('Bonjour mademoiselle', nom) ;
fin ;
fin.

33
Dr Ndi Nyoungui André
Algorithmique et structures de données

Exercice 3.5
Écrire un algorithme qui va répéter le traitement ci-dessus pour un nombre
quelconque de personne. La répétition s’arrête lorsque l’utilisateur entre un nom
égal à ‘*’.

L’algorithme est le suivant :


Algorithme Salutation ;
variable
nom : chaîne ;
sexe, marié : caractère ;
début
écrire('Quel est votre nom ?') ;
lire(nom) ;
tantque nom ≠ '*' faire
début
écrire('Quel est votre sexe (M ou F) ? ') ;
lire(sexe) ;
si sexe = 'M' alors
écrire('Bonjour monsieur', nom)
sinon
début
écrire('Êtes-vous marié (O ou N) ? ') ;
lire(marié) ;

si marié = 'O' alors


écrire('Bonjour madame', nom)
sinon
écrire('Bonjour mademoiselle', nom) ;
fin ;
fin ;
fin.

Exercice 3.6
Écrire un algorithme qui demande à l’utilisateur de donner son nom, son sexe, son
année de naissance et une année de référence puis affiche le message
« Monsieur … votre âge est de … ans » si la personne est de sexe masculin et le
message « Madame … votre âge est de … ans » si la personne est de sexe féminin.

L’algorithme est le suivant :


Algorithme Classement ;
variable

34
Dr Ndi Nyoungui André
Algorithmique et structures de données

nom : chaîne ;
naissance, référence, âge : entier ;
sexe : caractère ;
début
écrire('Quel est votre nom ? ') ;
lire(nom) ;
écrire('Quel est votre sexe (M ou F)? ') ;
lire(sexe) ;
écrire('Quelle est votre année de naissance ? ') ;
lire(naissance) ;
écrire('Quelle année de référence ? ') ;
lire(référence) ;
âge ← référence – naissance ;
si sexe = 'M' alors
écrire('Monsieur ', nom, 'votre âge est de', âge, 'ans')
sinon
écrire('Madame ', nom, 'votre âge est de', âge, 'ans')
fin.

Exercice 3.7
Écrire un algorithme qui va répéter le traitement ci-dessus pour un nombre
quelconque de personne. La répétition s’arrête lorsque l’utilisateur entre un nom
égal ‘*’.

L’algorithme est le suivant :


Algorithme Classement ;
variable
nom : chaîne ;
naissance, référence, âge : entier ;
sexe : caractère ;
début
écrire('Quel est votre nom ? (* pour terminer)') ;
lire(nom) ;
tantque nom ≠ '*' faire
début
écrire('Quel est votre sexe (M ou F)?') ;
lire(sexe) ;
écrire('Quelle est votre année de naissance ?') ;
lire(naissance) ;
écrire('Quelle année de référence ? ') ;
lire(référence) ;

35
Dr Ndi Nyoungui André
Algorithmique et structures de données

âge ← référence – naissance ;


si sexe = ‘M’ alors
écrire('Monsieur ', nom, 'votre âge est de ' , âge, '
ans')
sinon
écrire('Madame ', nom, 'votre âge est de ', âge, '
ans') ;

écrire('Quel est votre nom ? (* pour terminer)') ;


lire(nom) ;
fin ;
fin.

Exercice 3.8
Écrire un algorithme qui va répéter le traitement ci-dessus pour n personnes au
plus (n lu). La répétition s’arrête lorsque l’utilisateur entre un nom égal à ‘*’ ou
que le nombre de personnes traitées devient supérieur à n.

L’algorithme est le suivant :


Algorithme Classement ;
variable
nom : chaîne ;
naissance, référence, âge : entier ;
sexe : caractère ;
n, compteur : entier ;
début
écrire('Quel est le nombre de personne ?') ;
lire(n) ;
écrire('Quel est votre nom ? (* pour terminer) ') ;
lire(nom) ;
compteur ← 0 ;
tantque (nom ≠ '*') et (compteur < n) faire
début
écrire('Quel est votre sexe (M ou F)?') ;
lire(sexe) ;
écrire('Quelle est votre année de naissance ? ') ;
lire(naissance) ;
écrire('Quelle année de référence ?') ;
lire(référence) ;
âge ← référence – naissance ;
si sexe = ‘M’ alors

36
Dr Ndi Nyoungui André
Algorithmique et structures de données

écrire('Monsieur ', nom, ' votre âge est de' , âge, '
ans')
sinon
écrire('Madame ', nom, 'votre âge est de' , âge, 'ans') ;

écrire('Quel est votre nom ? (* pour terminer)') ;


lire(nom) ;
compteur ← compteur + 1 ;
fin ;
fin.

Exercice 3.9
Écrire un algorithme qui lit une suite de nombres positifs se terminant par –1 et
détermine le plus grand de ces nombres.

L’algorithme est le suivant :


Algorithme Plusgrand ;
variable
nombre, grand : entier ;
début
écrire('Entrez un nombre (-1 pour terminer) : ') ;
lire(nombre) ;
si nombre = - 1 alors
écrire('La liste est vide. ')
sinon
début
grand ← nombre ;
tantque (nombre ≠ -1) faire
début
écrire('Entrez un nombre (-1 pour terminer) : ') ;
lire(nombre) ;
si nombre ≠ - 1 alors
si nombre > grand alors
grand ← nombre ;
fin ;
écrire('Le plus grand nombre est : ' , grand) ;
fin
fin.

Exercice 3.10
Écrire un algorithme qui lit une suite de nombres positifs se terminant par –1 et
détermine le plus grand de ces nombres ainsi que sa position dans la liste.
37
Dr Ndi Nyoungui André
Algorithmique et structures de données

L’algorithme est le suivant :


Algorithme Plusgrand ;
variable
nombre, grand, position, compteur : entier ;
début
écrire('Entrez un nombre (-1 pour terminer) : ') ;
lire(nombre) ;
si nombre = - 1 alors
écrire('La liste est vide')
sinon
début
grand ← nombre ;
position ← 1 ;
compteur ← 1 ;
tantque (nombre ≠ -1) faire
début
écrire('Entrez un nombre (-1 pour terminer) : ') ;
lire(nombre) ;
si nombre ≠ - 1 alors
début
compteur ← compteur + 1 ;
si nombre > grand alors
début
grand ← nombre ;
position ← compteur ;
fin ;
fin ;
fin ;
écrire('Plus grand nombre : ', grand) ;
écrire('Position dans liste : ', position) ;
fin ;
fin.

Exercice 3.11
Quelle sera la sortie du segment d’algorithme ci-dessous ?

pour i ← 1 haut 5 faire


début
pour j ← 1 haut i faire
écrire('1') ;

38
Dr Ndi Nyoungui André
Algorithmique et structures de données

écrireln ;
fin ;

Réponse

1
11
111
1111
11111

Exercice 3.12
Quelle sera la sortie du segment d’algorithme ci-dessous ?

pour i ← 1 haut 6 faire


début
pour j ← 1 haut 6 faire
si (i = j) ou (i + j = 7) alors
écrire('1')
sinon
écrire('0') ;
écrireln ;
fin ;

Réponse

100001
010010
001100
001100
010010
100001

Exercice 3.13
Écrire un algorithme qui calcule la somme des carrés des n premiers entiers
naturels non nuls.

L’algorithme est le suivant :


Algorithme Calcul ;
variable
i, n, somme : entier ;
début

39
Dr Ndi Nyoungui André
Algorithmique et structures de données

écrire('Quel est la valeur de n ? ') ;


lire(n) ;
si n < 0 alors
écrire('Mauvaise donnée')
sinon
début
somme ← 0 ;
pour i ← 1 haut n faire
somme ← somme + i*i ;

écrire(somme);
fin;
fin.

Exercice 3.14
Écrire un algorithme qui lit un entier positif et calcule le factoriel de ce entier.

L’algorithme est le suivant :


Algorithme Calcul ;
variable
i, nombre, factoriel : entier ;
début
écrire('Quel est la valeur du nombre ?') ;
lire(nombre) ;
si nombre < 0 alors
écrire('Mauvaise donnée')
sinon
début
factoriel ← 1 ;
pour i ← 1 haut nombre faire
factoriel ← factoriel * i ;

écrire(factoriel);
fin;
fin.

Exercice 3.15
Le chercheur médiéval Leonardo (Fibonacci) da Pisa, a proposé la suite infinie
dans laquelle chaque terme est la somme des deux termes précédents. Le n ème
nombre de Fibonacci est défini récursivement de la manière suivante :

1. Si n est égal à 0 ou à 1 alors le nème nombre de Fibonacci est égal à n.

40
Dr Ndi Nyoungui André
Algorithmique et structures de données

2. Si n est supérieur ou égal à 2 alors le n ème nombre de Fibonacci est égal à


la somme des deux nombres de Fibonnaci précédents

Écrire un algorithme qui calcule et imprime les 100 premiers nombres de


Fibonacci.

L’algorithme est le suivant :


Algorithme Fibonacci ;
variable
n, premier, second, somme : entier ;
début
premier ← 1 ;
second ← 1 ;
écrire(premier) ;
écrire(second) ;
n←2;
tanqtue (n < 100) faire
début
somme ← premier + second ;
premier ← second ;
second ← somme ;
écrire(second) ;
n←n+1;
fin ;
fin.

Exercice 3.16
Écrire un algorithme qui calcule et imprime les rapports entre les 100 premières
paires de nombres de Fibonacci consécutifs.

L’algorithme est le suivant :


Algorithme Fibonacci ;
variable
n, premier, second, somme : entier ;
quotient : réel ;
début
premier ← 1 ;
second ← 1 ;
n←1;
tantque ( n ≤ 100) faire
début

41
Dr Ndi Nyoungui André
Algorithmique et structures de données

quotient ← premier/second ;
écrire(quotient) ;
somme ← premier + second ;
premier ← second ;
second ← somme ;
n←n+1;
fin ;
fin.

Exercice 3.17
En mathématiques et en sciences, on utilise fréquemment la constante
transcendentale e dont la valeur est approximativement égale à 2.718281. Les
étudiants de mathématiques savent que la série de Maclaurin ci-dessous peut
1 1 1
e=1  ⋯ ⋯
2! 3 ! n!
être utilisée pour représenter e :

Clairement, lorsque n devient grand, la contribution de chaque terme additionnel


devient très petite. Écrire un algorithme qui calcule et imprime les valeurs de e
obtenues en utilisant un nombre croissant de termes dans la série de Maclaurin
de e. L’itération s’arrête dès que le terme courant devient inférieur à un certain
epsilon.

L’algorithme est le suivant :


Algorithme Calcul ;
constante
epsilon = 0.0001 ;
variable
terme, valeur : réel ;
n : entier ;
début
terme ← 1 ;
n←0;
tantque terme > epsilon faire
début
n←n+1;
terme ← terme/n ;
valeur ← valeur + terme ;
écrireln(valeur) ;
fin ;
fin.

42
Dr Ndi Nyoungui André
Algorithmique et structures de données

Exercice 3.18
Lorsqu’un capital est déposé dans une banque qui paie les intérêts une fois par
mois, et lorsque le capital initial et les intérêts restent en dépôt, les intérêts
sont dits composés. La formule de calcul du capital en dépôt P, lorsque un capital
A est déposé initialement et lorsque les intérêts sont payés à un taux d’intérêt I
pour N mois est :
P= A∗ 1I N

Écrire un algorithme qui calcule et imprime le capital en dépôt P lorsque le capital


initial A est placé au taux d’intérêt I à la fin de chacun des n premiers mois.

L’algorithme est le suivant :


Algorithme CalculIntérêts ;
variable
capital, taux : réel ;
i, n : entier ;
début
écrire('Quel est le capital initial?') ;
lire(capital) ;
écrire('Quel est le taux de placement ?') ;
lire(taux) ;
écrire('Quel est le nombre de mois ?') ;
lire(n) ;
pour i ← 1 haut n faire
début
capital ← capital*(1 + taux) ;
écrireln('Mois n° : ', i, 'capital : ' , capital) ;
fin ;
fin.

Études de cas

Transaction sur un compte bancaire

Le programme de transaction va lire le solde courant, le montant du chèque et la


montant de chaque versement. Il va imprimer, sous une forme tabulaire, le
montant de chaque transaction et le solde après que la transaction est appliqué
au solde.

Algorithme GestionTransactions;
type
43
Dr Ndi Nyoungui André
Algorithmique et structures de données

Transactions = (retrait, versement, erreur) ;


variable
Solde, Montant : réel ;
Transaction : Transactions ;
stop : booléen ;
Code : entier ;
début
écrireln('CODE MONTANT SOLDE') ;
écrire('Solde courant : ')
lire(Solde) ;
répéter
écrire('Code transaction (1 : Retrait, 2 : Dépôt)') ;
lire(Code)
écrire('Montant opération : ') ;
lire(Montant) ;
stop ← vrai ;
si Code = 1 alors
Transaction ← retrait
sinon
si Code = 2 alors
Transaction ← dépôt
sinon
Transaction ← erreur ;
si Transaction = retrait alors
Solde ← Solde – Montant
sinon
si Transaction = dépôt alors
Solde ← Solde + Montant
sinon
début
écrire(Mauvais code de transaction) ;
écrire(Code, Montant) ;
stop ← faux ;
fin ;
écrireln(Code, Montant, Solde) ;
jusquà non stop.
fin.

Calcul de la racine carrée d’un nombre

44
Dr Ndi Nyoungui André
Algorithmique et structures de données

Examinons maintenant une application utilisant une boucle qui commence par une
valeur singulière et répète un ensemble d’opérations jusqu’à ce que la solution
désirée soit obtenue. Nous allons examiner un problème mathématique classique :
le calcul de la racine carrée d’un nombre. Il y a plusieurs algorithmes pour
calculer les racines carrées. Nous allons utiliser celui que l’on attribue à Isaac
Newton. La méthode de Newton utilise l’approche suivante : si r est une
approximation de la racine carrée d’un nombre x, alors (r + x/r)/2 est une
meilleure approximation de la racine carrée de x. On commence donc par une
approximation arbitraire, par exemple 1, et on répète le calcul de l’approximation
jusqu’à ce que la différence entre le carré de l’approximation et le nombre
devienne inférieure à un epsilon donné. Écrire un algorithme qui lit un nombre et
calcule sa racine carrée.

En considérant le fait que nous ne pouvons pas calculer la racine carrée d’un
nombre négatif, et que nous n’avons pas besoin de calculer une approximation de
la racine carrée de zéro, l’algorithme peut s’écrire de la manière :

Algorithme RacineCarrée ;
constante
epsilon = 0.0001 ;
variable
Racine, Nombre, Différence : réel ;
début
écrire('Entrez le nombre : ') ;
lire(Nombre) ;
si Nombre < 0 alors
écrire('Erreur de donnée – Valeur négative')
sinon
début
si Nombre = 0 alors
Racine ← 0
sinon
début
Racine ← 1 ;
répéter
Racine ← (Nombre/Racine + Racine)/2 ;
Différence ← Racine*Racine – Nombre ;
jusquà abs(Différence) > epsilon ;
écrire('La racine carrée de ’, Nombre, 'est : ', Racine) ;
fin ;
fin.

45
Dr Ndi Nyoungui André
Algorithmique et structures de données

Chapitré 4

Procédures et fonctions

Exercice 4.1
Écrire une fonction qui prend en entrée deux entiers positifs n et p et retourne
le nombre d’arrangements p à p de n éléments.

L’algorithme est le suivant :


fonction arrangement(n, p : entier) : entier ;
variable
i, dividende, diviseur : entier ;
début
si (n < p) alors
arrangement ← 0
sinon
début
dividende ← factoriel(n) ;
diviseur ← factoriel(n – p) ;
arrangement ← dividende div diviseur ;
fin ;
fin ;

Exercice 4.2
Une année est bissextile si son millésime est un multiple de 4, sauf les années de
début de siècle qui sont bissextiles si leur millésime est divisible par 400.
Écrire une fonction booléenne qui reçoit en entrée un entier naturel et
détermine si cet entier représente une année bissextile.

Première version

L’algorithme est le suivant :


fonction bissextile(année : entier) : booléen ;
début
si (année mod 4) ≠ 0 alors
bissextile ← faux
sinon
si ((année mod 100) = 0) et ((année mod 400) ≠ 0) alors
46
Dr Ndi Nyoungui André
Algorithmique et structures de données

bissextile ← faux
sinon
bissextile ← vrai ;
fin ;

Deuxième version

L’algorithme est le suivant :


fonction bissextile(année : entier) : booléen ;
début
si ((année mod 4) = 0) et (((année mod 100) ≠ 0) ou ((année mod 400) = 0))
alors
bissextile ← vrai
sinon
bissextile ← faux ;
fin ;

Exercice 4.3
Une boutique est ouverte de 7 heures à 13 heures et de 16 heures à 22 heures,
sauf le dimanche après-midi et le lundi toute la journée. Écrire un fonction
booléenne qui reçoit en entrée une heure (un entier naturel) et un jour (une
chaîne de caractère) et détermine si la boutique est ouverte le jour et à l’heure
indiqués..

L’algorithme est le suivant :


fonction boutique(heure : entier ; jour : chaîne) : booléen ;
début
si jour = 'lundi' alors
boutique ← faux
sinon
si jour = 'dimanche' alors
si (heure < 7) ou (heure > 13) alors
boutique ← faux
sinon
boutique ← vrai
sinon
si (heure < 7) ou ((heure > 13) et (heure < 16)) ou (heure > 22)
alors
boutique ← faux
sinon
boutique ← vrai ;

47
Dr Ndi Nyoungui André
Algorithmique et structures de données

fin ;

Deuxième version

fonction boutique(heure : entier ; jour : chaîne) : booléen ;


variable
ouvert : booléen ;
début
boutique ← faux ;
si (jour ≠ 'lundi') et (heure ≥ 7) et (heure ≤ 13) alors
boutique ← vrai
sinon
si (jour ≠ 'dimanche') et (jour ≠ 'lundi') et (heure ≥ 16) et (heure ≤
22) alors
boutique ← vrai ;
fin ;

Exercice 4.4
Les tarifs d’affranchissement d’une lettre sont les suivants :
en-dessous de 20g : 280 FCFA,
à partir de 20g, mais en-dessous de 50g : 440 FCFA,
à partir de 50g : 670 FCFA.
Écrire une fonction qui prend en entrée le poids d’une lettre et retourne le
montant de l’affranchissement de la lettre.

L’algorithme est le suivant :


fonction montant(poids : réel) : réel ;
début
si poids < 20 alors
montant ← 280
sinon
si poids < 50 alors
montant ← 440
sinon
montant ← 670 ;
fin ;

Exercice 4.5
Un entier positif est premier s’il est supérieur à deux et s’il n’est divisible que
par un et par lui-même. Écrire une fonction qui prend en entrée un entier positif
et détermine si cet entier est un nombre premier.

48
Dr Ndi Nyoungui André
Algorithmique et structures de données

fonction premier(nombre : entier): booléen;


variable
i : entier;
trouvé : booléen;
début
i ← 2;
trouvé ← vrai ;
tantque (i ≤ sqrt(nombre) et trouvé faire
début
si (nombre mod i = 0) alors
trouvé ← faux ;
i ← i + 1;
fin;
premier ← trouvé;
fin ;

Exercice 4.6
On souhaite calculer le montant des impôts dus par un contribuable en fonction
de son revenu imposable et de son nombre de parts fiscales. Les règles de calcul
sont les suivantes :
- le revenu par part fiscale est égale au quotient du revenu imposable par le
nombre de parts fiscales
- l’impôt par part fiscale est calculé selon le barème suivant :
• 0 si le revenu par part fiscale est inférieur à 50 000 F ;
• 10% sur la tranche du revenu par part comprise entre 50 000 F et 100
000 F ;
• 25% sur la tranche du revenu par part comprise entre 100 000 F et
200 000 F
• 50% sur le revenu par part fiscale est qui dépasse 200 000 F
- l’impôt total est égal au nombre de parts fiscales multiplié par l’impôt par
part fiscale

Écrire une fonction qui prend en entrée le revenu imposable et le nombre de


parts fiscales d’un contribuable et retourne le montant des impôts dus par ce
contribuable.

L’algorithme est le suivant :


fonction impôt(revimp, nbparts : réel) : réel ;
variable
revpart, impart, impôtdus : réel ;

49
Dr Ndi Nyoungui André
Algorithmique et structures de données

début
revpart ← revimp/nbparts ;

{Calcul de l’impôt par part fiscale}


si revenu ≤ 50000 alors
impart ← 0
sinon
si revenu ≤ 100000 alors
impart ← (revpart – 50000)*0.1
sinon
si revpart ≤ 200000 alors
impart ← (revpart – 100000)*0.25
sinon
impart ← (revpart – 200000)*0.5

impôt ← impart * nbparts ;


fin ;

Exercice 4.7
Lorsqu’un capital est déposé dans une banque qui paie les intérêts une fois par
mois et que le capital initial et les intérêts restent en dépôt, on dit que les
intérêts sont composés. La formule qui donne le capital courant P lorsque le
capital initial est A et que les intérêts sont payés au taux annuel I au bout de N
mois est :

P= A∗ 1I N

Écrire une fonction qui prend en entrée le capital initial A, le nombre d’années N
et calcule le capital courant P au bout des N mois.

L’algorithme est le suivant :


fonction capital(n : entier ; cap, taux : réel) : réel ;
variable
total : réel ;
i : entier ;
début
total ← cap ;
i←0;
tantque i < n faire
début
total ← total*(1 + taux);

50
Dr Ndi Nyoungui André
Algorithmique et structures de données

i←i+1;
fin ;
capital ← total ;
fin ;

Exercice 4.8
Écrire une procédure qui reçoit en entrée un entier naturel n, lit n nombre réels
et retourne le plus de ces nombres.

L’algorithme est le suivant :


procédure plusgrand(n : entier ; var grand : réel) ;
variable
nombre : réel ;
i : entier ;
début
si n ≤ 0 alors
écrire('La liste est vide')
sinon
début
écrire('Entrez un nombre') ;
lire(nombre) ;
grand ← nombre ;
i←1;
tantque (i < n) faire
début
écrire('Entrez un nombre') ;
lire(nombre) ;
i←i+1;
si nombre > grand alors
grand ← nombre ;
fin ;
fin ;
fin ;

Exercice 4.9
Écrire une procédure qui prend en entrée un entier naturel n, lit n nombres et
retourne le plus grand de ces nombres ainsi que sa position dans la liste.

L’algorithme est le suivant :


procédure plusgrandindice(n : entier ; var grand : réel ; var indice : entier) ;
variable

51
Dr Ndi Nyoungui André
Algorithmique et structures de données

nombre : réel ;
i : entier ;
début
si n ≤ 0 alors
écrire('La liste est vide')
sinon
début
écrire('Entrez un nombre') ;
lire(nombre) ;
grand ← nombre ;
i←1;
indice ← 1 ;
tantque i < n faire
début
écrire('Entrez un nombre') ;
lire(nombre) ;
i←i+1;
si nombre > grand alors
début
grand ← nombre ;
indice ← i ;
fin ;
fin ;
fin ;
fin ;

Exercice 4.10
Écrire une procédure qui prend en entrée un entier n, lit n nombres et retourne
le plus grand et le plus petit de ces nombres ainsi que leurs positions respectives
dans la liste.

L’algorithme est le suivant :


procédure grandpetit(n : entier ; var grand, petit : réel ; var indmax, indmin :
entier) ;
variable
nombre : réel ;
i : entier ;
début
si n ≤ 0 alors
écrire('La liste est vide')
sinon

52
Dr Ndi Nyoungui André
Algorithmique et structures de données

début
écrire('Entrez un nombre') ;
lire(nombre) ;
grand ← nombre ;
petit ← nombre ;
i←1;
indmax ← 1 ;
indmim ← 1 ;
tantque i < n faire
début
écrire('Entrez un nombre') ;
lire(nombre) ;
i←i+1;
si nombre > grand alors
début
grand ← nombre ;
indmax ← i ;
fin ;
sinon
si nombre < petit alors
début
petit ← nombre ;
indmin ← i ;
fin ;
fin ;
fin ;
fin ;

Exercice 4.11
Écrire une procédure qui teste si un nombre n, non négatif, est un carré parfait.
Cette procédure fournit deux résultats : un booléen qui est vrai si et seulement
si n est un carré parfait, et un entier égal à la partie entière de la racine carrée
de n.

L’algorithme est le suivant :


procédure carréparfait(n : entier ; var parfait : booléen ; var racine : entier) ;
variable
i : entier ;
début
i ← 0;
tantque i*i < n faire

53
Dr Ndi Nyoungui André
Algorithmique et structures de données

i←i+1;
si i*i = n alors
début
parfait ← vrai ;
racine ← i ;
fin ;
sinon
début
parfait ← faux ;
racine ← i - 1 ;
fin ;
fin ;

Exercice 4.12
Utiliser la procédure ci-dessus dans une autre procédure, qui, pour un nombre
entier, imprime la racine de sa racine carrée ou de la partie entière de sa racine
carrée, ou un message d’erreur si le nombre est négatif.

L’algorithme est le suivant :


procédure imprimeracine(nombre : entier) ;
variable
racine : entier ;
parfait : booléen ;
début
si nombre < 0 alors
écrire('Erreur de donnée – Valeur positive attendue')
sinon
début
carréparfait(nombre, parfait, racine);
si parfait alors
écrire('Racine de', nombre, ' = ', racine)
sinon
écrire('Partie entière racine de', nombre, ' = ', racine)
fin ;
fin ;

Exercice 4.13
Écrire une fonction qui calcule n^p, où p est un entier naturel et n un entier
quelconque.

L’algorithme est le suivant :

54
Dr Ndi Nyoungui André
Algorithmique et structures de données

fonction puissance(n, p : entier) : entier ;


variable
r, i : entier ;
début
si n = 0 alors
puissance ← 0
sinon
début
r ← 1;
i ← 0;
tantque i < p faire
début
r ← r*n ;
i←i+1;
fin ;
puissance ← r ;
fin ;

Exercice 4.14
Écrire une procédure qui prend en entrée trois nombres a, b et c et les permute
de telle sorte que l’on obtienne a ≤ b ≤ c.

On utilise la procédure permute qui permet de permuter les valeurs de nombres


a et b.

procédure permute(var a, b : entier) ;


variable
nombre : entier ;
début
nombre ← a ;
a←b;
b ← nombre ;
fin ;

L’algorithme est le suivant :


procédure permutation(a, b, c : entier) ;
début
si a > b alors
permute(a, b) ;
si b > c alors
permute(b, c) ;

55
Dr Ndi Nyoungui André
Algorithmique et structures de données

si a > b alors
permute(a, b) ;
fin ;

Exercice 4.15
Considérons la fonction suivante :

fonction Mystère(a : entier) : entier ;


début
si a < 0 alors
écrire(‘Erreur’)
sinon
si a = 0 alors
Mystère ← 0
sinon
Mystère ← a + mystère(a – 1)
fin ;

Quelle est la sortie de cette fonction en utilisant les paramètres effectifs


suivants ?
(a) 0 (b) –1
(c) 5 (d) 10

Exercice 4.16
Réécrire la fonction ci-dessus sous forme itérative.

fonction Mystère(a : entier) : entier ;


variable
i, somme : entier ;
début
somme ← 0 ;
si a < 0 alors
écrire(‘Erreur’)
sinon
pour i ← 1 haut a faire
somme ← somme + i ;

Mystère ← somme ;
fin ;

Exercice 4.17

56
Dr Ndi Nyoungui André
Algorithmique et structures de données

Écrire une version itérative de la fonction qui calcule le plus grand diviseur
commun de deux entiers positifs.

L’algorithme est le suivant :


fonction GCD(a, b : entier) : entier ;
variable
reste : entier ;
début
si a < b alors
permute(a, b)
sinon
si (a mod b = 0) alors
GCD ← b
sinon
début
tantque (a mod b ≠ 0) faire
début
reste ← a mod b ;
a←b;
b ← reste ;
fin ;
GCD ← reste ;
fin ;
fin ;

Exercice 4.18
Écrire une version itérative de la fonction qui calcule le nième nombre de
Fibonacci.

L’algorithme est le suivant :


fonction Fibonacci(n : entier) : entier ;
variable
i, premier, second, somme : entier ;
début
si (n = 0) ou (n = 1) alors
Fibonacci ← 1
sinon
début
premier ← 1 ;
second ← 1 ;
i←2;

57
Dr Ndi Nyoungui André
Algorithmique et structures de données

tanqtue (i ≤ n) faire
début
somme ← premier + second ;
premier ← second ;
second ← somme ;
i←i+1;
fin ;
Fibonacci ← somme ;
fin ;
fin.

Exercice 4.19
Écrire une version itérative de la fonction qui calcule les coefficients binomiaux.

L’algorithme est le suivant :


fonction binôme(n, p : entier) : entier ;
variable
i, numérateur, dénominateur : entier ;
début
si (n < p) alors
binôme ← 0
sinon
si (p = 0) ou (p = n) alors
binôme ← 1
sinon
début
numérateur ← 1 ;
pour i ← n bas (n – p + 1) faire
numérateur ← i*numérateur ;
dénominateur ← 1 ;
pour i ← (n – p) bas 1 faire
numérateur ← i*numérateur ;

binôme ← numérateur div dénominateur ;


fin ;
fin ;

Études de cas

Calcul de la dépréciation d’un bien économique

58
Dr Ndi Nyoungui André
Algorithmique et structures de données

Dans le but de calculer les taxes, les biens économiques peuvent être dépréciés
en utilisant l’une de trois méthodes différentes. L’approche la plus simple est
appelée la dépréciation linéaire « straight-line depreciation ». En utilisant cette
méthode, la valeur du bien décroît de la même quantité chaque année sur la
période totale. Ainsi, si un article est déprécié sur une période de n années, 1/n
de la valeur totale est déprécié chaque année.
Une deuxième méthode utilise le « double-declining balance depreciation ». Dans
cette méthode, la dépréciation autorisée chaque année est égale à la valeur
courante multipliée par 2/n, où n est le nombre d’années au cours desquelles
l’article doit être déprécié.
Une troisième méthode, appelée la méthode de la somme des chiffres « sum-of-
the-digits method », fonctionne de la manière suivante : D’abord, la somme des
nombres de 1 à n est calculée, où n est le nombre d’années au cours desquelles le
bien est déprécié. Ensuite, la dépréciation autorisée à la i-ème année est égale à
la valeur originale multipliée par (n – i) + 1 divisée par la somme des nombres.
Écrire trois fonctions différentes pour calculer la dépréciation d’un article en
utilisant chacune des méthodes ci-dessus.

fonction dépréciationlinéaire(valeur : réel ; i, n : entier) : entier ;


variable
k, somme : entier ;
début
somme ← 0 ;
k←1;
tantque k ≤ i faire
début
somme ← somme + k ;
k←k+1;
fin ;
dépréciationlinéaire ← somme * valeur/n ;
fin ;

fonction doubledeclining(valeur : réel ; i, n : entier) : entier ;


variable
nombre, facteur : entier ;
début
facteur ← 1 ;
k←1;
tantque k ≤ i faire
début
facteur ← (2/n)*facteur ;

59
Dr Ndi Nyoungui André
Algorithmique et structures de données

k←k+1;
fin ;
doubledeclining ← valeur * facteur ;
fin ;

fonction sommedeschiffres(valeur : réel ; i, n : entier) : entier ;


variable
k, somme : entier ;
début
somme ← 0 ;
k←1;
tantque k ≤ n faire
début
somme ← somme + k ;
k←k+1;
fin ;
sommedeschiffres ← ((n – i) + 1) * valeur/somme ;
fin ;

Construction du triangle de Pascal

On veut écrire une procédure pour construire les n premières lignes du triangle
de Pascal. Le triangle de Pascal est un tableau de nombres dont les entrées sont
les coefficients binomiaux


p
n
=
n!
p !  n− p  !

Les entrées du triangle sont telles que les nombres situés sur une ligne
correspondent à la même valeur de n tandis que les nombres situés sur une
colonne correspondent à la même valeur de p.

La construction du triangle de Pascal se fait ligne par ligne. On utilise pour cela
la fonction binôme que nous avons écrite dans le cours pour calculer les
coefficients binomiaux. Par exemple, les dix premières lignes du triangle de
Pascal correspondent au tableau de nombres suivants :

1
1 1
1 2 1

60
Dr Ndi Nyoungui André
Algorithmique et structures de données

1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1

L’algorithme est alors le suivant :


procédure Pascal(n : entier) ;
variable
k, p, terme : entier ;
début
k←0;
tantque (k ≤ n) faire
début
p←0;
tantque (p ≤ k) faire
début
terme ← binôme(k, p) ;
écrire(terme) ;
p←p+1;
fin ;
k←k+1;
écrireln ;
fin ;
fin ;

61
Dr Ndi Nyoungui André
Algorithmique et structures de données

Chapitre 5

Introduction aux structures


de données

Exercice 5.1
Écrire des définitions d’articles ,pour représenter les données suivantes :
(a) Un employé ayant des champs pour le nom, le numéro matricule, le salaire
brute et le net à percevoir.
(b) Une équipe de football ayant les champs pour le nom de l’équipe, le nombre de
matchs joués, le nombre de matchs gagnés, le nombre de matchs perdus, le
nombre de matchs nuls et le pourcentage de matchs gagnés.
(c) Un compte bancaire ayant des champs pour le numéro de compte, le nom du
titulaire du compte, l’adresse du titulaire, le solde courant et les intérêts
cumulés.
(d) Un numéro de téléphone ayant des champs pour la code de région, le préfixe
et le numéro.

temployé = article
nom : chaîne ;
matricule : chaîne ;
SalaireBrute : réel ;
SalaireNet : réel ;
fin ;

téquipe = article
NomEquipe : chaîne ;
MatchsJoués : entier ;
MatchsGagnés : entier ;
MatchsPerdus : entier ;
MatchsNuls : entier ;
Pourcentage : réel ;
fin ;

tcompte = article
Numéro : chaîne ;
NomTitulaire : chaîne ;
62
Dr Ndi Nyoungui André
Algorithmique et structures de données

Adresse : chaîne ;
Solde : réel ;
Intérêts : réel ;
fin ;

ttéléphone = article
CodeRégion : entier ;
Préfixe : entier ;
Numéro : entier ;
fin ;

Exercice 5.2
Écrire des procédure pour lire et écrire des article de type temployé.

procédure écrireemployé(empl: temployé) ;


début
écrireln('Nom : ', empl.Nom) ;
écrireln('Matricule: ', empl.Matricule) ;
écrireln('Salaire Brute : ', empl.SalaireBrute) ;
écrireln('Crédit foncier : ', empl.Taxes.CFC) ;
écrireln('Redance audio-visuelle : ', empl.Taxes.CRTV) ;
écrireln('Pesnion viellesse : ', empl.Taxes.CNPS) ;
écrireln('Net à percevoir : ', empl.SalaireNet) ;
fin ;

procédure lireemployé(var empl : temployé) ;


constante
tauxCFC = 0.07 ; {7%}
tauxCRTV = 0.06 ; {6%}
tauxCNPS = 0.01 ; {1%}
variable
taxes : réel ;
début
écrireln('Nom : ')
lire(empl.Nom) ;
écrireln('Matricule : ') ;
lire(empl.Matricule) ;
écrireln('Salaire Brute :');
lire(empl.SalaireBrute) ;
empl.Taxes.CFC ← tauxCFC * empl.SalaireBrute ;
empl.Taxes.CRTV ← tauxCRTV * empl.SalaireBrute ;

63
Dr Ndi Nyoungui André
Algorithmique et structures de données

empl.Taxes.CNPS ← tauxCNPS * empl.SalaireBrute ;


taxes ← empl.Taxes.CFC + empl.Taxes.CRTV + empl.Taxes.CNPS ;
empl.SalaireNet ← empl.SalaireBrure – taxes ;
fin ;

Exercice 5.3
Définir un type d’article avec variantes qui pourrait être utilisée pour stocker les
informations concernant une figure géométrique. L’article doit stocker la forme
(carré, triangle, rectangle ou cercle) et les dimensions appropriées. Écrire
ensuite une procédure pour lire les informations sur une figure et une fonction
qui prend en entrée une figure géométrique et retourne sa surface.

type
tforme = (Carré, Triangle, Rectangle, Cercle) ;
tfigure = article
case forme : tforme de
Carré : (côté : réel) ;
Triangle : (base, hauteur : réel) ;
Rectangle : (longueur, largeur : réel) ;
Cercle : (rayon : réel) ;
fin ;

procédure lirefigure(var figure : tfigure) ;


variable
nombre : entier ;
début
écrire('Quelle forme (1 : Carré, 2 : Triangle ; 3 : Rectangle, 4 : Cercle)') ;
lire(nombre) ;
si nombre = 1 alors
figure.forme ← Carré
sinon
si nombre = 2 alors
figure.forme ← Triangle
sinon
si nombre = 3 alors
figure.forme ← Rectangle
sinon
si nombre = 4 alors
figure.forme ← Cercle ;
si figure.forme = Carré alors
début

64
Dr Ndi Nyoungui André
Algorithmique et structures de données

écrire('Quel est le côté ?') ;


lire(figure.côté) ;
fin
sinon
si figure.forme = Triangle alors
début
écrire('Quelle est la base ?') ;
lire(figure.base) ;
écrire('Quelle est la hauteur ?') ;
lire(figure.hauteur) ;
fin
sinon
si figure.forme = Rectangle alors
début
écrire('Quelle est la largeur ?') ;
lire(figure.largeur) ;
écrire('Quelle est la longueur ?') ;
lire(figure.longueur) ;
fin
sinon
si figure.forme = Cercle alors
début
écrire('Quel est le rayon ?') ;
lire(figure.rayon) ;
fin ;
fin ;

fonction surfacefigure(figure : tfigure) : réel


constante
pi = 3.14149 ;
variable
surface : réel ;
début
si figure.forme = Carré alors
surface ← figure.côté * figure.côté
sinon
si figure.forme = Triangle alors
surface ← (base * hauteur)/2 ;
sinon
si figure.forme = Rectangle alors
surface ← figure.longueur * figure.largeur

65
Dr Ndi Nyoungui André
Algorithmique et structures de données

sinon
si figure.forme = Cercle alors
surface ← pi * figure.rayon * figure.rayon ;
surfacefigure ← surface ;
fin ;

Exercice 5.4
Soit le type article date, formé de trois nombres entiers qui indiquent
respectivement le jour, le mois et l’année.

type
tdate = article
Jour, mois, année : entier ;
fin ;

Écrire une fonction booléenne qui prend entrée deux dates date1 et date2 et
détermine si la date date1 vient avant la date date2.

L’algorithme est le suivant :


fonction avant(date1, date2 : tdate) : booléen ;
variable
av : booléen ;
début
av ← faux ;
si date1.année < date2.année alors
av ← vrai
sinon
si date1.année = date2.année alors
si date1.mois < date2.mois alors
av ← vrai
sinon
si date1.mois = date2.mois alors
si date1.jour < date2.jour alors
av ← vrai ;
avant ← av ;
fin ;

Études de cas

Exercice 5.7
Le service informatique d’un centre touristique conserve les informations sur les
clients en utilisant la structure suivante :
66
Dr Ndi Nyoungui André
Algorithmique et structures de données

type
tdomaine = (Cinéma, Musique, Sport, Lecture) ;
tclient = article
Nom : chaîne20 ;
Sexe : (Féminin, Masculin) ;
domaine : ensemble de tdomaine ;
Age : entier ;
fin ;

1. Écrire une procédure qui lit les informations sur un nouveau client et crée
un article pour ce client.
2. Écrire une procédure qui imprime les informations d’un client.
3. Écrire une fonction booléenne qui vérifie que deux clients sont
compatibles. Pour être compatibles, les clients doivent être de sexe
opposé, avoir un écart d’âge de six ans au plus et avoir au moins deux
intérêts en commun.
4. Écrire une procédure qui prend en entrée les informations sur un client et
une liste de n clients puis imprime la liste des clients qui lui sont
compatibles.

procédure lireclient(var cli : tclient) ;


variable
nombre : entier ;
choix : tdomaine ;
début
écrireln('Nom : ') ;
lire(cli.Nom) ;
écrireln('Sexe (1 : Féminin, 2 : Masculin)') ;
lire(nombre) ;
si nombre = 1 alors
cli.Sexe ← Féminin
sinon
cli.Sexe ← Masculin ;
écrireln('Age : ') ;
lire(cli.Age) ;
cli.Intérêts ← [ ] ;
choix ← Cinéma ;
tantque choix ≤ Lecture faire
début
sélection ord(choix) de
0 : écrireln('Aimez-vous le cinéma (0 ou 1) ?') ;

67
Dr Ndi Nyoungui André
Algorithmique et structures de données

1 : écrireln('Aimez-vous la musique (0 ou 1) ?') ;


2 : écrireln('Aimez-vous le sport (0 ou 1)?') ;
3 : écrireln('Aimez-vous la lecture (0 ou 1)?') ;
fin ;
lire(nombre) ;
si nombre = 1 alors
cli.domaine ← cli.domaine + [choix] ;
choix ← succ(choix) ;
fin ;
fin ;

procédure écrireclient(cli : tclient) ;


variable
nombre : entier ;
choix : tdomaine ;
début
écrireln('Nom : ', cli.Nom) ;
si cli.Sexe = Féminin alors
écrireln('Sexe : Féminin')
sinon
écrireln('Sexe : Masculin') ;
écrireln('Age : ', cli.Age) ;
choix ← Cinéma ;
tantque choix ≤ Lecture faire
début
si choix dans cli.domaine alors
sélection ord(choix) de
0 : écrireln('Cinéma') ;
1 : écrireln('Musique') ;
2 : écrireln('Sport') ;
3 : écrireln('Lecture') ;
fin ;
choix ← succ(choix) ;
fin ;
fin ;

fonction compatible(client1, client2 : tclient) : booléen ;


variable
compte : entier ;
choix : tdomaine ;
commun : ensemble de tdomaine ;

68
Dr Ndi Nyoungui André
Algorithmique et structures de données

début
compatible ← faux ;
si (client1.Sexe ≠ client2.Sexe) et (abs(client1.Age – client2.Age) ≤ 6)
alors
début
Commun ← client1.domaine * client2.domaine ;
compte ← 0 ;
pour choix ← Cinéma haut Lecture faire
si choix dans Commun alors
compte ← compte + 1 ;
si compte ≥ 2 alors
compatible ← vrai ;
fin ;
fin ;

On suppose que l’on a les définitions suivantes :

constante
taillemax = 1000 ;
type
vclient = vecteur[1..taillemax] de tclient ;

procédure listecompa(liste : vclient ; n : entier ; cli : tclient) ;


variable
i : entier ;
début
i←1;
k←0;
tantque i ≤ n faire
début
si compatible(liste[i], cli) alors
début
k←k+1;
écrireln('Client n° :', k)
écrireclient(liste[i]) ;
fin ;
i←i+1;
fin ;
fin ;

Exercice 5.8

69
Dr Ndi Nyoungui André
Algorithmique et structures de données

On veut écrire une procédure pour imprimer tous les nombres premiers compris
entre 1 et un certain entier positif arbitraire, nombremax. Pour obtenir les
nombres premiers, nous allons utiliser un algorithme classique connu comme
l’algorithme d’Eratosthenes. L’algorithme peut être décrit de la manière
suivante :
1. Commencer avec l’ensemble des entiers consécutifs compris entre 1 et
nombremax.
2. Supprimer de cet ensemble tous les multiples de 2. Ceux-ci ne sont pas
certainement des nombres premiers.
3. Trouver le prochain entier restant dans l’ensemble supérieur à celui dont
les multiples viennent d’être supprimés et supprimer tous ses multiples.
Ceux-ci ne peuvent pas être des nombres premiers.
4. Répéter l’étape 3 jusqu’à ce que l’entier dont les multiples viennent d’être
supprimés soit supérieur ou égal à la racine carrée de nombremax. Cette
condition de terminaison pour la suppression des entiers non premiers est
basée sur le fait que les deux facteurs dans un produit ne peuvent pas
être tous les deux supérieurs à la racine carrée du produit.
5. Les nombres qui restent dans l’ensemble après le processus de suppression
sont les entiers premiers compris entre 1 et nombremax.

On suppose que l’on a les définitions suivantes :

constante
taillemax = 100 ;
type
Nombres = ensemble de 2..taillemax ;

procédure erastosthenes(nombremax : entier) ;


variable
i, prime : entier ;
Sieve : Nombres ;
début
Sieve ← [2..nombremax] ;
prime ← 2 ;
tantque prime < sqrt(nombremax) faire
début
pour i ← succ(prime) haut nombremax faire
si (i dans Sieve) et (i mod prime = 0) alors
Sieve ← Sieve – [i] ;
prime ← succ(prime) ;
tantque non (prime dans Sieve) faire
prime ← succ(prime) ;

70
Dr Ndi Nyoungui André
Algorithmique et structures de données

fin ;
pour i ← 2 haut nombremax faire
si i dans Sieve alors
écrire(i) ;
fin ;

71
Dr Ndi Nyoungui André
Algorithmique et structures de données

Chapitre 6

Les vecteurs

Exercice 6.1
Écrire une procédure qui affiche les éléments d’un vecteur dans l’ordre
décroissant des indices.

Il s’agit d’une traduction directe des algorithmes présentés en cours dans


laquelle l’instruction traiter(liste[i]) est remplacée par une instruction d’écriture
de liste[i].

Première version, utilisation de la boucle tantque

L’algorithme est le suivant :


procédure écrirelistedg(liste : vélément ; n : entier) ;
variable
i : entier ;
début
i←n;
tantque i ≥ 1 faire
début
écrire(liste[i]) ;
i←i–1;
fin ;
fin ;

Deuxième version, utilisation de la boucle pour

procédure écrirelistedg(liste : vélément; n : entier) ;


variable
i : entier ;
début
pour i ← n bas 1 faire
écrire(liste[i]) ;
fin ;

Exercice 6.2

72
Dr Ndi Nyoungui André
Algorithmique et structures de données

Écrire la même procédure sous forme récursive.

L’algorithme est le suivant :


procédure écrirelistedg(liste : vélément ; n : entier) ;
début
si n = 1 alors
écrire(liste[n])
sinon
écrirelistedg(liste, n – 1) ;
fin ;

Exercice 6.3
Écrire une fonction qui calcule le nombre d’occurrences d’une valeur val dans un
vecteur de n éléments.

L’algorithme consiste à parcourir en incrémentant à chaque étape le compteur


lorsque liste[i] est égal à la valeur val. Le compteur est initialisé à zéro.

Première version, utilisation de la boucle tantque

L’algorithme est le suivant :


procédure effectifval(liste : vélément ; n : entier ; val : télément) : entier ;
variable
i, compte : entier ;
début
i←1;
compte ← 0 ;
tantque i ≤ n faire
début
si liste[i] = val alors
compte ← compte + 1 ;
i←i+1;
fin ;
effectifval ← compte;
fin ;

Deuxième version, utilisation de la boucle pour

L’algorithme est le suivant :


procédure effectifval(liste : vélément ; n : entier ; val : télément) : entier ;
variable
i, compte : entier ;
début

73
Dr Ndi Nyoungui André
Algorithmique et structures de données

compte ← 0 ;
pour i ← 1 haut n faire
si liste[i] = val alors
compte ← compte + 1 ;
effectifval ← compte;
fin ;

Exercice 6.4
On considère un vecteur de n entiers. Écrire une procédure qui imprime
uniquement les éléments de rang impaire.

Première version

On suppose que l’on dispose d’une fonction impair(nombre) qui retourne la valeur
vrai si nombre est impair et faux dans le cas contraire.

L’algorithme est le suivant :


procédure écrireimpairs(liste : vélément ; n : entier) ;
variable
i : entier ;
début
i←1;
tantque i ≤ n faire
début
si impair(i) alors
écrire(liste[i]) ;
i←i+1;
fin ;
fin ;

Deuxième version, utilisation d’une bascule

L’algorithme est le suivant :


procédure écrireimpairs(liste : vélément ; n : entier) ;
variable
i : entier ;
bascule : booléen ;
début
i←1;
bascule ← vrai ;
tantque i ≤ n faire
début
si bascule alors

74
Dr Ndi Nyoungui André
Algorithmique et structures de données

écrire(liste[i]) ;
i←i+1;
bascule ← non bascule ;
fin ;
fin ;

Exercice 6.5
Écrire une procédure qui reçoit en entrée un vecteur de n entiers et remplace
chaque élément du vecteur par la somme des éléments qui le précèdent y compris
lui-même.

Il suffit de conserver liste[1] et de remplacer liste[i] par liste[i] + liste[i - 1],


pour i allant de 2 à n.

Première version, utilisation de la boucle tantque

L’algorithme est le suivant :


procédure cumul(liste : vélément ; n : entier) ;
variable
i : entier ;
début
i←2;
tantque i ≤ n faire
début
liste[i] ← liste[i] + liste[i - 1] ;
i←i+1;
fin ;
fin ;

Deuxième version, utilisation de la boucle pour

L’algorithme est le suivant :


procédure cumul(liste : vélément ; n : entier) ;
variable
i : entier ;
début
pour i ← 2 haut n faire
liste[i] ← liste[i] + liste[i - 1] ;
fin ;

Exercice 6.6
On à demandé à n étudiants d’évaluer la qualité de la nourriture offerte à la
cafétéria sur une échelle de 1 à 10 (1 signifiant immangeable et 10, excellent).
75
Dr Ndi Nyoungui André
Algorithmique et structures de données

Écrire un algorithme pour lire les n réponses dans un vecteur d’entiers et


résumer le résultat du sondage.

On suppose que l’on a les définitions suivantes :

constante
tailleréponse = 1000 ;
taillefréquence = 10 ;
type
vréponse = vecteur[1..tailleréponse] de entier ;
vrésumé = vecteur[1..taillefréquence] de entier ;

procédure résumerondage(liste : vréponse ; n : entier, var fréquence : vrésumé :


entier) ;
variable
i, réponse : entier ;
début
i←1;
tantque i ≤ n faire
début
écrire(Quelle est votre note ?) ;
lire[liste[i]] ;
i←i+1;
fin ;
{Initialisation du vecteur des fréquences}
i←1;
tantque i ≤ n faire
début
fréquence[i] ← 0 ;
i←i+1;
fin ;
{Calcul des fréquences}
i←1;
tantque i ≤ n faire
début
fréquence[liste[i]] ← fréquence[liste[i]] + 1 ;
i←i+1;
fin ;
fin ;

Exercice 6.7

76
Dr Ndi Nyoungui André
Algorithmique et structures de données

Une compagnie paie ses n vendeurs sur la base d’une commission. Le vendeur
reçoit $50 par semaine plus 10% du montant de ses ventes cette semaine. Écrire
une procédure qui calcule le nombre de vendeurs qui perçoivent un salaire dans
chacun des intervalles suivants (utiliser un vecteur pour faire le compte).

[$50 , $100[
[$100 , $200[
[$200 , $300[
[$300 , $400[
[$400 , $500[
[$500 , ∞[

On suppose que l’on a les définitions suivantes :

constante
nbintervalles = 6 ;
nbvendeurs = 100 ;
type
vfréquence = vecteur[1..nbintervalles] de entier ;
vcommission = vecteur[1..nbvendeurs] de réel ;

L’algorithme consiste à lire la paie de chacun des n vendeurs et d’incrémenter le


compte correspondant.

Première version, utilisation des instructions si … alors … sinon imbriquées

L’algorithme est le suivant :


procédure distribution(var liste : vfréquence ; paie : vcommission ; n : entier) ;
variable
i : entier ;
paie : réel ;
début
{Initialisation du vecteur}
i←1
tantque i ≤ nbintervalles faire
début
liste[i] ← 0 ;
i ← i + 1;
fin;
i←0;
tantque i < n faire
début
i←i+1;

77
Dr Ndi Nyoungui André
Algorithmique et structures de données

si paie[i] < 100 alors


liste[1]← liste[+] + 1
sinon
si paie[i] < 200 alors
liste[2]← liste[2] + 1
sinon
si paie[i] < 300 alors
liste[3]← liste[3] + 1
sinon
si paie[i] < 400 alors
liste[4]← liste[4] + 1
sinon
si paie[i] < 500 alors
liste[5]← liste[5] + 1
sinon
liste[6]← liste[6] + 1 ;

fin ;
fin ;

Première version, utilisation de la fonction div pou minimiser le nombre de


tests

L’algorithme est le suivant :


procédure distribution(var liste : vfréquence ; paie : vcommission ; n : entier) ;
variable
i, indice : entier ;
début
{Initialisation du vecteur}
i←1
tantque i ≤ nbintervalles faire
début
liste[i] ← 0 ;
i ← i + 1;
fin;
i←1;
tantque i ≤ n faire
début
indice ← paie[i] div 100 ;
si indice < 5 alors
liste[indice + 1]← liste[indice + 1] + 1

78
Dr Ndi Nyoungui André
Algorithmique et structures de données

sinon
liste[6]← liste[6] + 1 ;
i ← i + 1;
fin ;
fin ;

Exercice 6.8
Une des techniques utilisées par les cryptographes pour déchiffrer les codes est
d’utiliser la fréquence avec laquelle les différents caractères apparaissent dans
un texte encodé. Écrire une procédure qui lit une chaîne de caractères se
terminant par un point et calcule la fréquence d’apparition de chaque caractère
dans le texte. On suppose que seules les lettres de l’alphabet anglais sont
concernées. La ponctuation est ignorée et aucune différence n’est faite entre les
lettres minuscules et majuscules.

On suppose que l’on les définitions suivantes :

type
ventier = vecteur['A' .. 'Z'] de entier ;

L’algorithme est le suivant :


procédure fréquence(var liste : ventier) ;
variable
i : entier ;
Ch : caractère ;
début
pour Ch ← 'A' haut 'Z' faire
liste[Ch] ← 0 ;
lire(Ch) ;
tantque Ch ≠ '.' faire
début
si Ch ≠ ' 'alors
liste[Maj(Ch)] ← liste[Maj(Ch)] + 1 ;
lire(Ch);
fin ;
fin ;

Exercice 6.9
Écrire une procédure qui reçoit en entrée un vecteur de n nombres réels et
détermine le plus grand et le second plus grand de ces nombres.

79
Dr Ndi Nyoungui André
Algorithmique et structures de données

L’algorithme est le suivant :


procédure deuxgrands(liste : vréels ; n : entier ; var grand, second : réel) ;
variable
i : entier ;
début
si n = 1 alors
début
grand ← liste[1] ;
second ← liste[1] ;
fin
sinon
début
{Recherche du plus grand}
grand ← liste[1] ;
pour i ← 2 haut n faire
si liste[i] > grand alors
grand ← liste[i];

{Recherche du second plus grand}


si liste[1] ≠ grand alors
second ← liste[1]
sinon
second ← liste[2];
pour i ← 2 haut n faire
si liste[i] ≠ grand alors
si liste[i] > second alors
second ← liste[i];
fin;
fin ;

Exercice 6.10
On suppose que l’on a les définition suivantes :

type
toption = (GBIO, MIP, GTE, GIN) ;
tétudiant = article
nom, chaîne ;
prénom : chaîne ;
sexe : (féminin, masculin) ;
matricule : chaîne ;
datenais : chaîne ;
lieunais : chaîne ;

80
Dr Ndi Nyoungui André
Algorithmique et structures de données

option : toption ;
fin ;
vétudiant = vecteur[1..100] de tétudiant ;

1. Écrire un algorithme pour lire un vecteur de n étudiants.


2. Écrire un algorithme pour écrire un vecteur de n éléments.
3. Écrire un algorithme qui délivre le nombre de filles dans un vecteur de n
étudiants.
4. Écrire un algorithme qui délivre le nombre de garçons et le nombre de
filles dans un vecteur de n étudiants.
5. Écrire un algorithme qui délivre le nombre d’étudiants inscrits dans une
discipline donnée.

Ces algorithmes sont une traduction directe des algorithmes présentés dans le
cours.

1°/ Lecture d’un vecteur d’étudiants

procédure lirevecteur(var liste : vétudiant ; var n : entier) ;


variable
i, numéro : entier ;
début
écrire('Quelle est la taille du vecteur ? ') ;
lire(n) ;
i←0;
tantque i < n faire
début
i←i+1;
écrireln('Nom : ') ;
lire(liste[i].nom)
écrireln('Prénom : ') ;
lire(liste[i].prénom) ;
écrireln('Sexe (1 : Féminin, 2 : Masculin) : ') ;
lire(numéro) ;
si numéro = 1 alors
liste[i].sexe ← féminin
sinon
liste[i].sexe ← masculin ;
écrireln(‘Matricule :’) ;
lire(liste[i].matricule) ;
écrireln('Date de naissance (jour/mois/année) : ') ;
lire(liste[i].datenais) ;

81
Dr Ndi Nyoungui André
Algorithmique et structures de données

écrireln('Lieu de naissance : ') ;


lire(liste[i].lieunais) ;
écrireln('Option (1 : MIP, 2 : GTE, 3 : GIN, 4 : GBIO) ') ;
lire(numéro) ;
sélection numéro de
1 : liste[i].Option ← MIP ;
2 : liste[i].Option← GTE ;
3 : liste[i].Option ← GIN ;
4 : liste[i].Option ← GBIO ;
fin ;
fin ;
fin ;

2°/ Impression d’un vecteur d’étudiants

procédure écrirevecteur(var liste : vétudiant ; n : entier) ;


variable
i : entier ;
début
i←0;
tantque i < n faire
début
i←i+1;
écrireln('Nom : ', liste[i].nom) ;
écrireln('Prénom : ', liste[i].prénom) ;
si liste[i].sexe = féminin alors
écrireln('Sexe : Féminin')
sinon
écrireln('Sexe : Masculin') ;
écrireln('Matricule : ', liste[i].matricule) ;
écrireln('Date de naissance : ', liste[i].datenais) ;
écrireln('Lieu de naissance : ', liste[i].lieunais) ;
sélection liste[i].option de
GBIO : écrireln('Génie Biologique') ;
MIP : écrireln('Maintenance Industrielle') ;
GTE : écrireln('Génie Thermique et Energétique') ;
GIN : écrireln('Génie Informatique') ;
fin ;
fin ;
fin ;

3°/ Calcul du nombre de filles dans un vecteur


82
Dr Ndi Nyoungui André
Algorithmique et structures de données

fonction nombrefilles(var liste : vétudiant ; n : entier) : entier ;


variable
i, compte : entier ;
début
i←0;
compte ← 0 ;
tantque i < n faire
début
i←i+1;
si liste[i].sexe = féminin alors
compte ← compte + 1 ;
fin ;
nombrefilles ← compte ;
fin ;

4°/ Calcul du nombre de filles et de garçons dans un vecteur

procédure distribution(var liste : vétudiant ; n : entier ; var nbfilles, nbgarçons :


entier) ;
variable
i : entier ;
début
i←0;
nbfilles ← 0 ;
nbgarçons ← 0 ;
tantque i < n faire
début
i←i+1;
si liste[i].sexe = féminin alors
nbfilles ← nbfilles + 1
sinon
nbgarçons ← nbgarçons + 1 ;
fin ;
fin ;

5°/ Calcul de l’effectif d’une filière

fonction effectif(var liste : vétudiant ; n : entier ; option : toption) : entier ;


variable
i, compte : entier ;
début

83
Dr Ndi Nyoungui André
Algorithmique et structures de données

i←0;
compte ← 0 ;
tantque i < n faire
début
i←i+1;
si liste[i].option = option alors
compte ← compte + 1 ;
fin ;
effectif ← compte ;
fin ;

Exercice 6.11
Écrire une fonction qui calcule le produit des éléments d’un vecteur de n nombres
réels (penser au cas où un élément serait nul).

L’algorithme est le suivant :


fonction produitliste(liste : vréels ; n : entier) : réel ;
variable
i : entier ;
produit : réel ;
début
si n = 0 alors
produitliste ← 0
sinon
début
produit ← 1 ;
i←1;
tantque (i ≤ n) et (produit ≠ 0) faire
début
si liste[i] = 0 alors
produit ← 0 ;
sinon
produit ← liste[i]*produit ;
i ← i + 1;
fin ;
fin ;
produitliste ← produit ;
fin ;

Exercice 6.12

84
Dr Ndi Nyoungui André
Algorithmique et structures de données

Écrire de plusieurs manières différentes une fonction qui délivre l’indice de la


valeur val dans un vecteur liste[1..n] si val appartient au vecteur et 0 si val
n’appartient pas au vecteur. Préciser dans chaque cas si c’est la première ou la
dernière occurrence que l’on a trouvée.

Recherche de la première occurrence

L’algorithme est le suivant :


fonction indicepremier(liste : vélément ; n : entier ; val : télément) : entier ;
variable
i : entier ;
début
i←1;
tantque (i ≤ n) et alors (liste[i] ≠ val) faire
i ← i + 1;
si i > n alors
indicepremier ← 0
sinon
indicepremier ← i ;
fin ;

Deuxième version

L’algorithme est le suivant :


fonction indicepremier(liste : vélément ; n : entier ; val : télément) : entier ;
variable
i : entier ;
début
i←1;
tantque (i < n) et (liste[i] ≠ val) faire
i ← i + 1;
si liste[i] ≠ val alors
indicepremier ← 0
sinon
indicepremier ← i ;
fin ;

Recherche de la dernière occurrence

Dans un premier temps, on peut penser à parcourir le vecteur de la gauche vers


la droite, en rangeant successivement tous les indices i tels que liste[i] = val dans

85
Dr Ndi Nyoungui André
Algorithmique et structures de données

une variable indice. La dernière valeur de indice sera bien celle de la dernière
occurrence de val.

L’algorithme est alors le suivant :


fonction indicedernier(liste : vélément ; n : entier ; val : télément) : entier ;
variable
i, indice : entier ;
début
i←1;
indice ← 0 ;
tantque i ≤ n faire
début
si liste[i] = val alors
indice ← i ;
i ← i + 1;
fin;
indicedernier ← indice ;
fin ;

Deuxième méthode

On peut remarquer que l’algorithme ci-dessus, malgré sa simplicité, est très


coûteux ; en effet il fait parcourir le vecteur entier dans tous les cas. Il est bien
plus efficace de reprendre les principes des algorithmes de recherche de la
première occurrence, mais en effectuant un parcours de la droite vers la gauche.

L’algorithme est le suivant :


fonction indicedernier(liste : vélément ; n : entier ; val : télément) : entier ;
variable
i : entier ;
début
i←n;
tantque (i ≥ n) et alors (liste[i] ≠ val) faire
i ← i - 1;
indicedernier ← i ;
fin ;

Exercice 6.13
Écrire une fonction entière qui retourne la place de la première occurrence de la
valeur val dans un vecteur trié liste[1..n] si val appartient au vecteur liste, et 0 si
val n’appartient à liste.

86
Dr Ndi Nyoungui André
Algorithmique et structures de données

Le raisonnement est semblable à celui du cours. Il suffit de modifier le type de


la fonction. En se basant sur accèstrié3, on obtient :

L’algorithme est le suivant :


fonction indicepremiertrié(liste : vélément ; n : entier ; val : télément) : entier ;
variable
i : entier ;
début
si val > liste[n] alors
indicepremiertrié ← 0
sinon
début
i←1;
tantque liste[i] < val faire
i ← i + 1;
si liste[i] = val alors
indicepremiertrié ← i
sinon
indicepremiertrié ← 0 ;
fin ;
fin ;

Exercice 6.14
Même question pour la dernière occurrence.

L’algorithme est le suivant :


fonction indicederniertrié(liste : vélément ; n : entier ; val : télément) : entier ;
variable
i : entier ;
début
si (val < liste[1]) ou (val > liste[n]) alors
indicederniertrié ← 0
sinon
début
i←n;
tantque liste[i] > val faire
i ← i - 1;
si liste[i] = val alors
indicederniertrié ← i
sinon

87
Dr Ndi Nyoungui André
Algorithmique et structures de données

indicederniertrié ← 0 ;
fin ;
fin ;

Exercice 6.15
Modifier les fonctions dichotomie ci-dessus afin qu’elles retournent la place de
élément dans le vecteur liste si élément est présent dans le vecteur et 0 sinon
(on supposera que le vecteur est trié sans répétition)

Version itérative

Il suffit de modifier le type de la fonction et de remplacer la variable booléenne


trouvé par une variable entière indice. Celle-ci est initialisée à zéro, on ne lui
affectera une valeur non nulle m que si liste[m] = elem. Par conséquent, non
trouvé est équivalent à indice = 0. On suppose qu’il y a une seule occurrence de
elem dans liste, donc si indice ≠ 0 on peut s’arrêter avec la certitude d’avoir
trouvé sans ambiguïté la valeur cherchée.

L’algorithme est alors le suivant :


fonction indicedicho(liste : vélément ; n : entier ; elem : télément) : entier ;
variable
inf, sup, m, indice : entier ;
début
indice ← 0 ;
inf ← 1 ;
sup ← n
tantque (inf ≤ sup) et (indice = 0) faire
début
m ← (inf + sup) div 2 ;
si liste[m] = elem faire
indice ← m
sinon
si liste[m] < elem alors
inf ← m + i
sinon
sup ← m - 1 ;
fin ;
indicedicho ← indice ;
fin ;

Version récursive

88
Dr Ndi Nyoungui André
Algorithmique et structures de données

Il suffit, comme ci-dessus, de modifier le type de la fonction pour qu’elle délivre


plutôt un entier.

L’algorithme est alors le suivant :


fonction indicedicho(liste : vélément ; inf, sup : entier ; elem : télément) : entier ;
variable
m : entier ;
début
si inf > sup alors
indicedicho ← 0
sinon
début
m ← (inf + sup) div 2 ;
si liste[m] = elem faire
indicedicho ← m
sinon
si liste[m] < elem alors
indicedicho ← indicedicho(liste, m + 1, sup, elem)
sinon
indicedicho ← indicedicho(liste, inf, m - 1, elem)
fin ;
fin;

Exercice 6.16
Écrire un algorithme pour supprimer un sous-vecteur donnée dans un vecteur.

On doit disposer d’une fonction recherchesliste qui recherche le sous-vecteur


dans le vecteur, en délivrant l’indice de son premier élément si on le trouve, et 0
si le sous-vecteur n’appartient pas au vecteur. Il ne restera plus alors qu’à
décaler les éléments à droite du sous-vecteur vers la gauche pour obtenir la
suppression.

L’algorithme de suppression est alors le suivant :


procédure supprimesliste(var liste : vélément ; var n : entier ; sliste : vélément ;
ns : entier ; var possible : booléen) ;
variable
i, p : entier ;
début
possible ← faux ;
p ← recherchesliste(liste, 1, n, sliste, ns) ;
si p ≠ 0 alors
début

89
Dr Ndi Nyoungui André
Algorithmique et structures de données

possible ← vrai ;
i←1;
tantque i ≤ ns faire
début
tasser(liste, n, p) ;
i←i+1;
fin ;
fin ;
fin ;

Pour écrire la fonction recherchesliste, on introduit la notion de préfixe : un


sous-vecteur sliste est un préfixe d’un vecteur liste si liste = sliste || listeb,
listeb ≠ [ ]. On commencera donc par écrire une fonction qui recherche si un
sous-vecteur sliste est préfixe d’un vecteur liste[i..n] donné. Il suffit de
comparer les éléments de même rang depuis liste[i] et le début de sliste, en
s’arrêtant dès que l’on trouve une différence. On commence par vérifier si
liste[1..n] contient au moins autant d’éléments que sliste.

L’algorithme est alors le suivant :


fonction préfixe(liste, sliste : vélément ; i, n, ns : entier) : booléen ;
variable
j ; entier ;
début
si i > n – ns + 1 alors
préfixe ← faux
sinon
début
j←1;
tantque (j ≤ ns) et alors (liste[i + j - 1] = slsite[j]) alors
j←j+1;
préfixe ← j > ns ;
fin ;
fin ;

L’accès au sous-vecteur sliste dans un vecteur liste[1..n] consiste alors à


chercher si sliste est préfixe d’un sous-vecteur liste[i..n] obtenu en éliminant les
premiers éléments. On cherchera si sliste est préfixe de liste[i..n], i = 1, 2,…, en
s’arrêtant dès que la condition est vérifiée.

L’algorithme est alors le suivant :


fonction recherchesliste(liste : vélément ; i, n, sliste : vélément ; ns : entier) :
entier ;

90
Dr Ndi Nyoungui André
Algorithmique et structures de données

variable
j : entier ;
début
j←i;
tantque (i ≤ n – ns + 1) et alors non préfixe(liste, sliste, j, n, ns) faire
j←j+1;
si j > n – ns + 1 alors
rechercehsliste ← 0
sinon
recherchesliste ← j ;
fin;

Exercice 6.17
Écrire un algorithme pour remplacer un sous-vecteur donné dans un vecteur par
un autre.

Une méthode consiste à écrire d’abord une procédure qui remplace les ns
premiers éléments de liste[i..n] par les nr éléments de rliste. Pour cela, on sera
amené à décaler la suite de liste à gauche ou à droite, selon que ns est supérieur
ou inférieur à nr.

procédure remplacepréfixe(var liste : vélément ; var i, n : entier ;


rliste : vélément ; nr, ns : entier) ;
variable
i : entier ;
début
si ns > nr alors {décalage à gauche}
début
j←1;
tantque j ≤ ns – nr faire
début
tasser(liste, n, i) ;
j←j+1;
fin ;
fin
sinon {décalage à droire}
début
j←1;
tantque j ≤ nr – ns faire
début
étendre(liste, n, i) ;
j←j+1;
91
Dr Ndi Nyoungui André
Algorithmique et structures de données

fin ;
fin ;
j ← 1 ; {remplacement}
tantque j ≤ nr faire
début
liste[i + j - 1] ← rliste[j];
j ← j + 1;
fin;
n ← n + nr – ns;
fin;

Le remplacement du sous-vecteur sliste par rliste consiste alors à chrecher


l’indice i de la première occurrence de sliste dans liste, et, si celle-ci existe, à
remplacer le préfixe sliste de liste[i..n] par rliste.

L’algorithme est alors le suivant :


procédure remplacesliste(var liste : vélément ; var n : entier ;
sliste, rliste : vélément ; ns, nr : entier) ;
variable
i : entier ;
début
i ← recherchesliste(liste, 1, n, slsite, ns) ;
si i ≠ 0 alors
remplacepréfixe(liste, i, n, rliste, nr, ns) ;
fin ;

Exercice 6.18
Écrire un algorithme pour remplacer toutes les occurrences d’un sous-vecteur
donnée dans un vecteur par un autre.

La procédure cherché découle facilement de celle de l’exercice précédent : il


suffit de répéter les opérations de recherche et de remplaceme,nt jusqu’au
moment où sliste ne figure plus dans liste. On aura soin de remettre à jour
l’indice de début de slsite, afin d’éviter une itération sans fin au cas où rlsite
serait égal à slsite.

L’algorithme est alors le suivant :


procédure remplacesliste(var liste : vélément ; var n : entier ;
sliste, rliste : vélément ; ns, nr :
entier) ;
variable
i : entier ;

92
Dr Ndi Nyoungui André
Algorithmique et structures de données

début
i ← rechercheslsite(liste, 1, n, sliste, ns) ;
tantque i ≠ 0 faire
début
remplacersliste(liste, i, n, rliste, nr, ns) ;
i ← rechercheslsite(liste, i, n, sliste, ns) ;
fin ;
fin ;

Exercice 6.19
Écrire un algorithme pour nettoyer un texte (vecteur de caractères), en
éliminant les espaces superflus : chaque fois que l’on trouve une suites d’espaces,
on les supprime tous sauf un.

Une première approche consisterait à retasser le vecteur chaque fois que l’on
trouve deux espaces consécutifs, afin d’en éliminer un :

L’algorithme est alors le suivant :


procédure supprimespace(var liste : vcaractère ; var n : entier) ;
variable
i : entier ;
début
i←2;
tantque i ≤ n faire
si (liste[i - 1] = ' ') et (liste[i] = ' ') alors
début
j←i;
tantque j < n faire
début
liste[j] ← liste[j + 1]
j←j+1;
fin ;
n←n–1;
fin
sinon
i←i+1;
fin ;

Cette méthode implique beaucoup de décalages. Il est plus économique de


marquer les espaces superflus en les remplaçant par un caractère bidon (par
exemple $) puis procéder à l’opération supprimebidon afin d’éliminer tous les

93
Dr Ndi Nyoungui André
Algorithmique et structures de données

caractères bidon en un seul passage. On notera que c’est le premier de deux


espaces consécutifs qui devra être marqué et non le second.

L’algorithme est alors le suivant :


procédure supprimespace(var liste : vcaractère ; var n : entier) ;
variable
i : entier ;
début
i←2;
tantque i ≤ n faire
début
si (liste[i - 1] = ' ') et (liste[i] = ' ') alors
liste[i - 1] ← '$';
i←i+1;
fin ;
supprimebidon(liste, n, '$') ;
fin ;

Exercice 6.20
Modifier le tri par bulles pour obtenir un vecteur trié par ordre décroissant.

Rappelons que le tri par bulles consiste a effectuer des permutations telles que
le plus grand élément de liste[1..n – k + 1] se retrouve placé dans liste[n – k + 1].
On répète l’opération pour k allant de 1 à n – 1.

Pour obtenir un tri par ordre décroissant, on procède la manière suivante : au lieu
de ranger dans liste[n – k + 1] le maximum de liste[1..n – k + 1], on y range plutôt
le minimum. Il suffit alors d’inverser le sens du test qui détermine si l’on doit
permuter deux éléments consécutifs ou non.

L’algorithme devient alors le suivant :


procédure tribullesdec(var liste : vélément ; n : entier) ;
variable
i, k : entier ;
stop : booléen;
début
stop ← faux ;
k←1;
tantque (k ≤ n – 1) et non stop faire
début
i←1;
stop ← vrai ;

94
Dr Ndi Nyoungui André
Algorithmique et structures de données

tantque i ≤ n - k faire
début
si liste[i] < liste[i + 1] alors
début
permute(liste[i], liste[i + 1]) ;
stop ← faux ;
fin ;
i←i+1;
fin;
k←k+1;
fin;
fin;

Exercice 6.21
Modifier le tri par sélection pour obtenir un vecteur trié par ordre décroissant.

Le tri par sélection du cours permet d’obtenir un vecteur trié par ordre
croissant, en permutant d’abord le minimum de liste[1..n] avec liste[1], puis le
minimum de liste[2..n] avec liste[2], et ainsi de suite jusqu’à liste[n-1]. Pour
obtenir un vecteur trié par ordre décroissant, deux adaptations sont possibles :

Première solution

On opère sur les maxima au lieu de minima, en les rangeant dans l’ordre liste[1],
…,liste[n].

La fonction auxiliaire indicemin est donc remplacée par la suivante :


fonction indicemax(liste : vélément ; k, n : entier) : entier ;
variable
i, indice : entier ;
début
indice ← k ;
i←k+1;
tantque i ≤ n faire
début
si liste[indice] < liste[i] alors
indice ← i ;
i←i+1;
fin;
indicemax ← indice ;
fin ;

95
Dr Ndi Nyoungui André
Algorithmique et structures de données

La procédure de tri par sélection par ordre décroissant est alors identique à
celle du cours, en remplaçant indicemim par indicemax.

procédure trisélectiondec(var liste : vélément ; n : entier) ;


variable
i, k : entier ;
début
k←1;
tantque k < n faire
début
i ← indicemax(liste, k, n) ;
si i ≠ k alors
permute(liste[i], liste[k]);
k←k+1;
fin;
fin;

Exercice 6.22
Modifier le tri par insertion pour obtenir un vecteur trié par ordre décroissant.

Rappelons que le principe de la méthode de tri par insertion consiste à effectuer


des insertions telles que à chaque étape l’élément liste[i] est inséré dans le sous-
vecteur liste[1..i-1] de telle sorte que le sous-vecteur liste[1..i] reste trié. On
opère l’opération pour i allant de 2 à n.

Pour obtenir un tri par ordre décroissant, on va procéder à des insertions telles
que à chaque étape l’élément liste[i] est inséré dans le sous-vecteur liste[1..i-1]
de telle sorte que le sous-vecteur liste[1..i] reste trié par ordre décroissant. Il
suffit alors d’inverser le sens de du test dans le processus de recherche de la
place de liste[i] dans le sous-vecteur liste[1..i-1].

L’algorithme devient alors le suivant :


procédure trinsertiondec(var liste: vélément ; n : entier) ;
variable
i, j , k : entier ;
elem: télément;
début
i←2;
tantque i ≤ n faire
début
j←1;
tantque (liste[j] ≥ liste[i]) et (j < i) faire
96
Dr Ndi Nyoungui André
Algorithmique et structures de données

j←j+1;

si j < i alors
début
elem ← liste[i];
pour k ← i bas j + 1 faire
liste[k] ← liste[k - 1];

liste[j] ← elem;
fin;
i←i+1;
fin;
fin;

Exercice 6.23
Modifier le tri par insertion par bissection pour obtenir un vecteur trié par
ordres décroissant.

Rappelons que le tri par insertion par bissection est une variante du tri par
insertion dans laquelle on utilise la méthode recherche dichotomique pour
trouver la place de l’élément liste[i] dans le sous-vecteur liste[1..i-1].

Pour obtenir un vecteur trié par ordre décroissant, il suffit de trouver une
version de la méthode de recherche dichotomique qui opère dans un vecteur trié
par ordre décroissant. Ceci est immédiat car il suffit d’inverser le sens du test
qui détermine la moitié du vecteur à explorer à chaque étape.

La fonction auxiliaire indichotomie est donc remplacée par la suivante :


fonction indichodec(liste : vélément; n : entier ; elem : télément) : entier ;
variable
inf, sup, m : entier ;
début
si liste[n]≤ elem alors
indichodec ← n + 1
sinon
début
inf ← 1 ;
sup ← n ;
tantque inf < sup faire
début
m ← (inf + sup) div 2 ;
si liste[m] ≥ elem alors
inf ← m + 1
97
Dr Ndi Nyoungui André
Algorithmique et structures de données

sinon
sup ← m ;
fin ;
indichodec ← sup ;
fin ;
fin ;

La procédure tribissectiondec est donc identique à celle du cours, en remplaçant


indichotomie par indichodec.

procédure tribissection(var liste: vélément ; n : entier) ;


variable
i, j : entier ;
elem: télément;
début
i←2;
tantque i ≤ n faire
début
j ← indichodec(liste, i – 1, liste[i]) ;
si j < i alors
début
elem ← liste[i];
pour k ← i bas j + 1 faire
liste[k] ← liste[k - 1];

liste[j] ← elem ;
fin;
i ← i + 1;
fin;
fin;

Exercice 6.24
Modifier le Quicksort pour obtenir un vecteur trié par ordre décroissant.

Nous donnons une traduction immédiate de la première version du Quicksort


donnée dans le cours. Il suffit d’inverser le principe de déplacement des
éléments par rapport au pivot pour amener à droite les éléments inférieurs au
pivot et à gauche les éléments qui sont supérieurs au pivot.

L’algorithme est alors le suivant :


procédure Quicksort(var liste : vélément ; inf, sup : entier) ;
variable
L, R, place : entier ;
98
Dr Ndi Nyoungui André
Algorithmique et structures de données

début
place ← pivot(liste, inf, sup) ;
si place ≠ 0 alors
début
L ← place + 1 ;
R ← sup ;
tantque L ≤ R faire
début
tantque liste[L] > liste[place] faire
L←L+1;

tantque liste[R] ≥ liste[place] faire


R←R–1;

permute(liste[L], liste[R])
fin ;
permute(liste[place], liste[R]) ;
Quicksort(liste, inf, R – 1) ;
Quicksort(liste, R + 1, sup)
fin;
fin;

Exercice 6.25
Écrire un algorithme pour calculer la réunion de deux ensembles représentés par
des vecteurs.

L’algorithme se divise en deux parties distinctes :


• copier dans liste3 tous les éléments de liste1 ;
• copier dans liste3 tous les éléments de liste2 qui ne sont pas dans liste1.

L’algorithme est alors le suivant :


procédure union(liste1, liste2 : vélément ; n1, n2 : entier ;
var liste3 : vélément ; var n3 : entier) ;
variable
i, j : entier ;
trouvé: booléen;
début
i←1;
n3 ← 0 ;
tantque i ≤ n1 faire
début
n3 ← n3 + 1 ;
liste3[n3] ← liste1[i] ;
99
Dr Ndi Nyoungui André
Algorithmique et structures de données

i←i+1;
fin ;
i←1;
tantque i ≤ n2 faire
début
trouvé ← faux ;
j←1;
tantque (j ≤ n1) et non trouvé faire
début
si liste2[j] = liste1[i] alors
trouvé ← vrai ;
j←j+1;
fin ;
si non trouvé alors
début
n3 ← n3 + 1 ;
liste3[n3] ← liste2[i] ;
fin;
i←i+1;
fin ;
fin ;

Exercice 6.26
Écrire un algorithme pour calculer l’intersection de deux ensembles représentés
par des vecteurs.

L’algorithme consiste à recopier dans liste3 les éléments de liste1 qui sont aussi
dans liste2.

L’algorithme est alors le suivant :


procédure intersection(liste1, liste2 : vélément ; n1, n2 : entier ;
var liste3 : vélément ; var n3 : entier) ;
variable
i, j : entier ;
trouvé: booléen;
début
i←1;
n3 ← 0 ;
tantque i ≤ n1 faire
début
j←1;
trouvé ← faux ;
10
0 Dr Ndi Nyoungui André
Algorithmique et structures de données

tantque (j ≤ n2) et non trouvé faire


début
si liste2[j] = liste1[i] alors
trouvé ← vrai ;
j←j+1;
fin ;
si trouvé alors
début
n3 ← n3 + 1 ;
liste3[n3] ← liste1[i] ;
fin;
i←i+1;
fin ;
fin ;

Exercice 6.27
Écrire un algorithme pour calculer la différence ensembliste de deux ensembles
représentés par des vecteurs.

L’algorithme consiste à recopier dans liste3 les éléments de liste1 qui ne sont pas
dans liste2.

L’algorithme est alors le suivant :


procédure différence(liste1, liste2 : vélément ; n1, n2 : entier ;
var liste3 : vélément ; var n3 : entier) ;
variable
i, j : entier ;
trouvé: booléen;
début
i←1;
n3 ← 0 ;
tantque i ≤ n1 faire
début
j←1;
trouvé ← faux ;
tantque (j ≤ n2) et non trouvé faire
début
si liste2[j] = liste1[i] alors
trouvé ← vrai ;
j←j+1;
fin ;
si non trouvé alors
10
1 Dr Ndi Nyoungui André
Algorithmique et structures de données

début
n3 ← n3 + 1 ;
liste3[n3] ← liste1[i] ;
fin;
i←i+1;
fin ;
fin ;

Exercice 6.28
Écrire un algorithme pour calculer la différence symétrique de deux ensembles
représentés par des vecteurs.

On utilise la relation : A ∆ B = (A ∪ B) \ (A ∩ B).

L’algorithme est alors le suivant :


procédure diffsymétrique(liste1, liste2 : vélément ; n1, n2 : entier ;
var liste3 : vélément ; var n3 : entier) ;
variable
m1, m2 : entier ;
A, B: VECTEUR;
début
union(liste1, liste2, A, n1, n2, m1) ;
intersection(liste1, liste2, B, n1, n2, m2) ;
différence(A, B, liste3, m1, m2, n3) ;
fin ;

Exercice 6.29
Un palindrome est une chaîne de caractères qui se lit de la manière de la gauche
vers la droite et de la droite vers la gauche. Écrire une fonction qui prend en
entrée une chaîne de caractères et détermine si c’est un palindrome ou non.

Première version, comparaison progressive des lettres symétriques de la


chaîne

L’algorithme est le suivant :


procédure palindrome(chaîne : vcaractère; n : entier) : booléen ;
variable
i, : entier ;
palind : booléen;
début
palind ← vrai ;
i←i;
tantque (i ≤ (n div 2)) et palind faire
10
2 Dr Ndi Nyoungui André
Algorithmique et structures de données

si chaîne[i] ≠ chaîne[n – i + 1] alors


trouvé ← faux
sinon
i←i+1;
palindrome ← palind ;
fin;

Deuxième version, calcul de la chaîne inverse avant comparaison

procédure palindrome(chaîne : vcaractère; n : entier) : booléen ;


variable
i, : entier ;
inverse: vcaractère;
début
i←i;
tantque i ≤ n faire
début
inverse[n – i + i] ← chaîne[i] ;
i←i+1;
fin ;
palindrome ← inverse = chaîne ;
fin;

Exercice 6.30
Écrire une procédure qui reçoit en entrée deux matrices réelles de m lignes et n
colonnes et retourne la somme des deux matrices.

L’algorithme est le suivant :


procédure somme(A, B : tmatrice ; var C : tmatrice ; m, n :entier) ;
variable
i, j : entier ;
début
pour i ← 1 haut m faire
pour j ← 1 haut n faire
C[i, j] ← A[i, j] + B[i, j] ;
fin;

Exercice 6.31
Écrire une procédure qui reçoit en entrée une matrice réelle A de m lignes et n
colonnes et une matrice B réelle de n lignes de p colonnes retourne le produit AB
de ces deux matrices.

10
3 Dr Ndi Nyoungui André
Algorithmique et structures de données

L’algorithme est le suivant :


procédure produit(A, B : tmatrice ; var C : tmatrice ; m, n, p :entier) ;
variable
i, j, k : entier ;
début
pour i ← 1 haut m faire
pour j ← 1 haut p faire
début
C[i, j] ← 0;
pour k ← 1 haut n faire
C[i, j] ← C[i, j] + A[i, k]*B[k, j];
fin;
fin;

Exercice 6.32
Une matrice de N lignes et N colonnes est dite symétrique si A[i, j] = [j, i] pour
couple (i, j). Écrire une fonction qui prend en une matrice réelle de N lignes et N
colonnes et détermine si la matrice est symétrique.

L’algorithme est le suivant :


fonction symétrique(A : tmatrice ; n :entier) ;
variable
i, j : entier ;
stop: booléen;
début
stop ← vrai ;
i←1;
tantque (i < n) et stop faire
début
j←1;
tantque (j < i) et stop faire
début
si A[i, j] ≠ A[j, i] alors
stop ← faux
sinon
j ← j + 1;
i ← i + 1;
fin;
symétrique ← stop ;
fin;

10
4 Dr Ndi Nyoungui André
Algorithmique et structures de données

Exercice 6.33
Écrire une fonction qui prend en entrée une matrice réelle de m lignes et n
colonnes et retourne le plus grand élément de cette matrice.

L’algorithme est le suivant :


fonction plusgrand(A : tmatrice ; m, n :entier) : réel ;
variable
i, j : entier ;
grand: réel;
début
grand ← A[1,1] ;
i←1;
tantque i ≤ m faire
début
j←1;
tantque j ≤ n faire
début
si grand < [i, j] alors
grand ← A[i, j];
j←j+1;
fin ;
i ← i + 1;
fin;
plusgrand ← grand ;
fin;

Exercice 6.34
Écrire une procédure qui prend en entrée une matrice réelle de m lignes et n
colonnes et retourne le plus grand élément de cette matrice ainsi sa position
ligne/colonne.

L’algorithme est le suivant :


procédure posplusgrand(A : tmatrice ; m, n :entier ; var grand : réel ;
var ligne, colonne : entier);
variable
i, j : entier ;
grand: réel;
début
garnd ← A[1,1] ;
ligne ← 1 ;
colonne ← 1 ;

10
5 Dr Ndi Nyoungui André
Algorithmique et structures de données

pour i ← 1 haut m faire


pour j ← 1 haut n faire
si grand < [i, j] alors
début
grand ← A[i, j];
ligne ← i ;
colonne ← j ;
fin ;
fin;

Exercice 6.35
Écrire une procédure qui calcule la transposée d’une matrice réelle.

L’algorithme est le suivant :


procédure transposée(var A, B : tmatrice ; m, n :entier) ;
variable
i, j : entier ;
début
i←1;
tantque i ≤ m faire
début
j←1;
tantque j ≤ n faire
début
B[j, i] ← A[i, j] ;
j←j+1;
fin ;
i←i+1;
fin ;
fin;

Exercice 6.36
Un carré magique est un tableau de N lignes et N colonnes d’entiers de
l’intervalle [1.. N*N] tel que les sommes des termes de chaque ligne, chaque
colonne et de chaque diagonale principale sont égales. Écrire une fonction qui
prend en entrée une matrice de N lignes et N colonnes d’entiers de l’intervalle
[1.. N*N] et détermine si la matrice est un carré magique.

L’algorithme est le suivant :


fonction carrémagique(A : tmatrice ; n :entier) : booléen ;
variable

10
6 Dr Ndi Nyoungui André
Algorithmique et structures de données

i, j : entier ;
courante, somme, diag1, diag2 : réel ;
magique : booléen ;
début
{Vérifier la conformité des lignes}
courante ← 0 ;
pour j ← 1 haut n faire
courante ← courante + A[1, j] ;
magique ← vrai ;
i←2;
tantque (i ≤ n) et magique faire
début
somme ← 0 ;
pour j ← 1 haut n faire
somme ← somme + A[i, j] ;
si courante ≠ somme alors
magique ← faux ;
i←i+1;
fin ;
{Vérifier la conformité des colonnes}
j←1;
tantque (j ≤ n) et magique faire
début
somme ← 0 ;
pour i ← 1 haut n faire
somme ← somme + A[i, j] ;
si courante ≠ somme alors
magique ← faux ;
j←j+1;
fin ;
{traitement des diagonales}
si magique alors
début
diag1 ← 0 ;
pour i ← n haut n faire
diag1 ← diag1 + A[i, i] ;
diag2 ← 0 ;
pour j ← 1 haut n faire
diag2 ← diag2 + A[n - j + 1, j] ;
fin;
carrémagique ← magique et (diag1 = courante) et (diag2 = courante) ;

10
7 Dr Ndi Nyoungui André
Algorithmique et structures de données

fin;

Exercice 6.37
Écrire une fonction qui prend en entrée une matrice réelle de m lignes et n
colonnes et retourne le numéro de la ligne dont la somme des coefficients est
maximum.

L’algorithme est le suivant :


fonction lignemax(A : tmatrice ; m, n :entier) : entier ;
variable
i, j, ligne : entier ;
somme, grand : réel ;
début
somme ← 0 ;
pour j ← 1 haut n faire
somme ← somme + A[1, j] ;
grand ← somme ;
ligne ← 1 ;
pour i ← 2 haut m faire
début
somme ← 0 ;
pour j ← 1 haut n faire
somme ← somme + A[i, j] ;
si grand < somme alors
début
grand ← somme ;
ligne ← i ;
fin ;
fin ;
lignemax ← ligne ;
fin;

Exercice 6.38
Écrire une procédure qui prend en entrée un entier n et retourne la matrice des
n premières lignes du triangle de Pascal.

On suppose que l’on a les définition suivantes :

constante
taillemax = 100 ;
type
tmatrice = tableau[0..taillemax, 0..taillemax] de entier ;

10
8 Dr Ndi Nyoungui André
Algorithmique et structures de données

L’algorithme est le suivant :


procédure trianglepascal(nblignes : entier ; var A : tmatrice) ;
variable
n, p : entier ;
début
{On initialise toutes les entrées à zéro}
pour n ← 0 haut nblignes faire
pour p ← 0 haut nblignes faire
A[n, p] ← 0 ;

{Construction du triangle}
n←0;
tantque n < nblignes faire
début
A[n, 0] ← 1 ;
p←1;
tantque p ≤ n faire
début
A[n, p] ← A[n - 1, p - 1] + A[n - 1, p] ;
p←p+1;
fin ;
n←n+1;
fin ;
fin ;

Exercice 3.39
On veut écrire pour calculer la liste des nombres premiers compris entre 1 et un
certain entier positif arbitraire, nombremax. Pour obtenir les nombres premiers,
nous allons utiliser un algorithme classique connu comme l’algorithme
d’Eratosthenes. L’algorithme peut être décrit de la manière suivante :
1. Commencer avec le vecteur des entiers consécutifs compris entre 1 et
nombremax.
2. Mettre à zéro tous les multiples de 2. Ceux-ci ne sont pas certainement
des nombres premiers.
3. Trouver le prochain entier non nul dans le vecteur supérieur à celui dont
les multiples viennent d’être mis à zéro et mettre à zéro tous ses
multiples. Ceux-ci ne peuvent pas être des nombres premiers.
4. Répéter l’étape 3 jusqu’à ce que l’entier dont les multiples viennent d’être
mis à zéro soit supérieur ou égal à la racine carrée de nombremax. Cette
condition de terminaison pour la mise à zéro des entiers non premiers est

10
9 Dr Ndi Nyoungui André
Algorithmique et structures de données

basée sur le fait que les deux facteurs dans un produit ne peuvent pas
être tous les deux supérieurs à la racine carrée du produit.
5. Les nombres non nuls dans le vecteur après le processus de mise à zéro
sont les nombres premiers compris entre 1 et nombremax.

On suppose que l’on a les définitions suivantes :

constante
taillemax = 1000 ;
type
vnombre = vecteur[1..taillemax] de entier ;

procédure erastosthenes(nombremax : entier ; var liste : vnombre ; var n :


entier) ;
variable
i, prime : entier ;
Sieve : vnombre ;
début
i←1;
tantque i ≤ nombremax faire
début
Sieve[i] ← i + 1 ;
i ← i + 1;
fin;
prime ← 2 ;
tantque prime < sqrt(nombremax) faire
début
pour i ← succ(prime) haut nombremax faire
si (i ≠ 0) et (i mod prime = 0) alors
Sieve[i] ← 0 ;
prime ← succ(prime) ;
tantque non (prime ≠ 0) faire
prime ← succ(prime) ;
fin ;
n←0;
pour i ← 2 haut nombremax faire
si Sieve[i] ≠ 0 alors
début
n←n+1;
liste[n] ← i ;
fin ;
fin ;

11
0 Dr Ndi Nyoungui André
Algorithmique et structures de données

Études de cas

Dans ces études de cas, nous allons appliquer les algorithmes sur les vecteurs
(création, parcours, recherche, insertion, suppression, tri) à des structures de
données plus ou moins complexes.

Gestion des étudiants

On souhaite gérer une liste d’étudiants à l’aide de quelques algorithmes simples


sur les vecteurs (parcours, recherche, insertion, suppression, tri). Les
informations retenues pour chaque étudiant sont le numéro matricule, le nom
(nom et prénom), le sexe , la date de naissance, le lieu de naissance, la filière, le
nombre et la liste des cours de la filière. Bien entendu, le numéro matricule sera
différent pour chaque étudiant.

On suppose que l’on a les définitions suivantes :

constante
taillemax = 100 ;
nbmax = 20 ;
type
tdate = article
jour, mois, année : entier ;
fin ;
tcours = article
code : entier ;
intitulé : chaîne ;
examenpartiel : réel ;
examenfinal : réel ;
fin ;
vcours = vecteur[1..nbmax] de tcours ;
tétudiant = article
matricule : chaîne ;
nom : chaîne ;
sexe : (Féminin, Masculin) ;
annéenais : tdate ;
lieunaiss : chaîne ;
filière : chaîne ;
nbcours : entier ;
courspris : vcours ;

11
1 Dr Ndi Nyoungui André
Algorithmique et structures de données

fin ;
vétudiant = vecteur[1..taillemax] de tétudiant ;

On suppose que le vecteur est trié par ordre alphabétique et que tous étudiants
de la même filière ont les mêmes cours.

1°/ Écrire un algorithme pour créer un vecteur de n étudiants.

2°/ Écrire un algorithme qui imprime le nom, la date de naissance, le lieu de


naissance et la spécialité de chacun des étudiants enregistrés dans un vecteur de
n étudiants.

3°/ Écrire une fonction qui retourne le nombre d’étudiants d’une filière donnée
contenus dans un vecteur de n étudiants.

4°/ Écrire une procédure qui retourne le nombre de filles et le nombre de


garçons présents dans un vecteur de n étudiants.

5°/ Écrire un algorithme pour afficher le matricule, le nom, le lieu de naissance


et la spécialité de chacun des étudiants dont l’année de naissance est comprise
entre aninf et ansup dans un vecteur de n étudiants.

6°/ Écrire une fonction qui retourne la position d’un étudiant de matricule donné
dans un vecteur de n étudiants. La fonction retourne zéro si l’étudiant concerné
n’est pas présent dans la liste.

7°/ Écrire une procédure pour insérer un nouvel étudiant dans un vecteur de n
étudiants. La procédure doit d’abord vérifier qu’il n’existe pas encore un étudiant
ayant le même matricule.

8°/ Écrire une procédure qui supprime un étudiant de matricule donné dans un
vecteur de n étudiants.

9°/ Écrire un algorithme qui calcule le nombre d’unités de valeur validées par un
étudiant de matricule donné.

10°/ Écrire une fonction qui retourne la moyenne des notes d’un étudiant de
matricule donné dans une unité de valeur de code donné.

11°/ Écrire une fonction qui retourne la moyenne générale des notes d’un
étudiant de matricule donné.

11
2 Dr Ndi Nyoungui André
Algorithmique et structures de données

12°/ Écrire un algorithme qui classe par ordre de mérite, par rapport à la
moyenne générale des notes, les étudiants d’une filière donnée. À moyenne égale,
les étudiants seront classés par ordre alphabétique.

Solution

1°/ Écrire un algorithme qui crée un vecteur de n étudiants.

Nous écrivons d’abord une procédure auxiliaire pour lire un étudiant.

procédure lireétudiant(var étudiant : tétudiant) ;


variable
i, choix : entier ;
début
écrire('Matricule : ') ;
lireln(étudiant.matricule) ;
écrire('Nom : ') ;
lireln(étudiant.nom) ;
écrire('Sexe (0 : Féminin, 1 : Masculin ') ;
lireln(choix) ;
si choix = 0 alors
étudiant.sexe ← Féminin
sinon
étudiant.sexe ← Masculin ;
écrire('Date de naissance(jour/mois/année)') ;
lireln(étudiant.datenais.jour, étudiant.datenais.mois,
étudiant.datenais.année) ;
écrire('Lieu de naissance : ') ;
lireln(étudiant.lieunais) ;
écrire('Filière : ') ;
lireln(étudiant.filière) ;
écrire('Nombre de cours : ') ;
lireln(étudiant.nbcours) ;
i←1;
tantque i ≤ nbcours faire
début
écrire('Code du cours : ') ;
lireln(étudiant.courspris[i].code) ;
écrire('Intitulé du cours : ') ;
lireln(étudiant.courspris[i].intitulé) ;
écrire('Examen partiel : ') ;

11
3 Dr Ndi Nyoungui André
Algorithmique et structures de données

lireln(étudiant.courspris[i].examenpartiel) ;
écrire('Examen final : ') ;
lireln(étudiant.courspris[i].examenfinal) ;
i←i+1;
fin ;
fin ;

procédure créervecteur(var liste : vétudiant ; var n : entier) ;


variable
i : entier ;
début
écrire('Nombre étudiants : ') ;
lire(n) ;
i←1;
tantque i ≤ n faire
début
lireétudiant(liste[i]) ;
i←i+1;
fin ;
fin ;

2°/ Écrire un algorithme qui imprime le nom, le prénom, la date de naissance, le


lieu de naissance et la spécialité de chacun des étudiants enregistrés dans un
vecteur de n étudiants.

Nous écrivons d’abord une procédure auxiliaire pour imprimer un étudiant.

procédure imprimeétudiant(étudiant : tétudiant) ;


variable
jour, mois, année : entier ;
début
écrireln('Matricule : ', étudiant.matricule) ;
écrireln('Nom : ', étudiant.nom) ;
si étudiant.sexe = Féminin alors
écrireln('Sexe : Féminin')
sinon
écrireln('Sexe : Masculin') ;
jour ← étudiant.datenais.jour ;
mois ← étudiant.datenais.mois ;
année ← étudiant.datenais.année) ;
écrireln('Date de naissance : ', jour, '/', mois, '/', année) ;

11
4 Dr Ndi Nyoungui André
Algorithmique et structures de données

écrireln('Lieu de naissance : ', étudiant.lieunais) ;


écrireln('Filière : ', étudiant.filière) ;
fin ;

procédure imprimervecteur(var liste : vétudiant ; n : entier) ;


variable
i : entier ;
début
i←1;
tantque i ≤ n faire
début
imprimeétudiant(liste[i]) ;
i←i+1;
fin ;
fin ;

3°/ Écrire une fonction qui retourne le nombre d’étudiants d’une filière donnée
contenus dans un vecteur de n étudiants.

fonction effectifilière(liste : vétudiant ; n : entier ; nomfil : chaîne) : entier ;


variable
i, compte : entier ;
début
i←1;
compte ← 0
tantque i ≤ n faire
début
si liste[i].filière = nomfil alors
compte ← compte + 1 ;
i←i+1;
fin ;
effectifilière ← compte ;
fin ;

4°/ Écrire une procédure qui retourne le nombre de filles et le nombre de


garçons présents dans un vecteur de n étudiants.

procédure nbgarçonsfilles(liste : vétudiant ; n : entier ; var nbgar, nbfil :


entier) ;
variable
i : entier ;

11
5 Dr Ndi Nyoungui André
Algorithmique et structures de données

début
i←1;
nbgar ← 0 ;
nbfil ← 0 ;
tantque i ≤ n faire
début
si liste[i].sexe = féminin alors
nbfil ← nbfil + 1
sinon
nbgar ← nbgar + 1 ;
i←i+1;
fin ;
fin ;

5°/ Écrire un algorithme pour afficher le matricule, le nom, le lieu de naissance


et la spécialité de chacun des étudiants dont l’année de naissance est comprise
entre aninf et ansup dans un vecteur de n étudiants.

procédure imprimersliste(liste : vétudiant ; n, annéeinf, annéesup : entier) ;


variable
i : entier ;
début
i←1;
tantque i ≤ n faire
début
si (liste[i].datenais.année ≥ aninf) et (liste[i].datenais.année ≤ ansup)
alors
début
écrireln('Matricule : ', étudiant.matricule) ;
écrireln('Nom : ', étudiant.nom) ;
écrireln('Lieu de naissance : ', étudiant.lieunais) ;
écrireln('Filière : ', étudiant.filière) ;
fin ;
i←i+1;
fin ;
fin ;

6°/ Écrire une fonction qui retourne la position d’un étudiant de matricule donné
dans un vecteur de n étudiants. La fonction retourne zéro si l’étudiant concerné
n’est pas présent dans la liste.

11
6 Dr Ndi Nyoungui André
Algorithmique et structures de données

fonction recherche(liste : vétudiant ; n : entier ; matricule : chaîne) : entier ;


variable
i : entier ;
début
i←1;
tantque (i ≤ n) et alors (liste[i].matricule ≠ matricule) faire
i←i+1;
si i ≤ alors
recherche ← i
sinon
recherche ← 0 ;
fin ;

7°/ Écrire une procédure pour insérer un nouvel étudiant dans un vecteur de n
étudiants. La procédure doit d’abord vérifier qu’il n’existe pas encore un étudiant
un étudiant ayant le même matricule.

Nous écrivons d’abord les procédures auxiliaires position et insertplace.

fonction position(liste : vétudiant ; n : entier ; étudiant : tétudiant) : entier ;


variable
inf, sup, m : entier ;
début
si (liste [n] ≤ étudiant.nom) alors
position ← n + 1
sinon
début
inf ←1 ;
sup ←n ;
tantque (inf < sup) faire
début
m ← (inf + sup) div 2 ;
si (liste [m] ≤ étudiant.nom) alors
inf ← m + 1
sinon
sup ← m ;
fin ;
position ← sup ;
fin ;
fin ;

11
7 Dr Ndi Nyoungui André
Algorithmique et structures de données

procédure insertplace (var liste : vétudiant ; var n : entier ;


p : entier ; étudiant : tétudiant) ;
variable
i : entier ;
début
n ← n+1 ;
i←n;
tantque (i > p) faire
liste[i] ← liste[i - 1] ;

liste[p] ← elem ;
fin ;

procédure insertion(var liste : vétudiant ; var n : entier ; étudiant : tétudiant ;


var possible : booléen) ;
variable
p : entier ;
début
indice ← recherche(liste, n, étudiant.matricule) ;
possible ← faux ;
si (indice = 0) et (n ≤ taillemax) alors
début
possible ← vrai ;
si n = 0 alors
début
n←1;
liste[n] ← elem ;
fin
sinon
début
p ← position(liste, n, étudiant) ;
insertplace(liste, n, p, étudiant);
fin;
fin;
fin;

8°/ Écrire une procédure qui supprime un étudiant de matricule donné dans un
vecteur de n étudiants.

9°/ Écrire un algorithme qui calcule le nombre d’unités de valeur validées par un
étudiant de matricule donné.

11
8 Dr Ndi Nyoungui André
Algorithmique et structures de données

10°/ Écrire une fonction qui retourne la moyenne des notes d’un étudiant de
matricule donné dans une unité de valeur de code donné.

11°/ Écrire une fonction qui retourne la moyenne générale des notes d’un
étudiant de matricule donné.

12°/ Écrire un algorithme qui classe par ordre de mérite, par rapport à la
moyenne générale des notes, les étudiants d’une filière donnée. À moyenne égale,
les étudiants seront classés par ordre alphabétique.

Stock de voitures

Un marchand de véhicules d’occasion souhaite gérer son stock à l’aide de


procédures simples sur les vecteurs. On suppose que le stock de véhicules, de
100 voitures au plus, peut être représenté à l’aide d’un tableau en mémoire.

Les seules informations retenues pour chaque voiture seront le numéro


d’immatriculation et son année de mise en service, sa marque et son modèle, ainsi
que le prix. Bien entendu, le numéro d’immatriculation sera différent pour chaque
voiture.

Les déclarations de types utilisées seront les suivantes :

type
tvoiture = article
numéro : chaîne ;
année : entier ;
marque, modèle : chaîne ;
prix : réel ;
fin ;
vvoiture = vecteur[1..100] de tvoiture ;

On suppose que le vecteur est trié par ordre croissant sur les numéros des
véhicules.

1°/ Écrire une procédure qui prend en entrée un vecteur de n voitures, une
marque et modèle et affiche l’année et le prix de chacune des voitures de le
marque et du modèle demandés

11
9 Dr Ndi Nyoungui André
Algorithmique et structures de données

2°/ Écrire une procédure qui prend en entrée un vecteur de n voitures, un prix
inférieur et un prix supérieur et affiche l’année, la marque et le modèle de
chacune des voitures dont le prix est compris entre les deux prix.

3°/ Écrire une procédure qui prend en entrée un vecteur de n voitures et un


numéro et retourne position du vecteur dans le vecteur. La procédure retourne
également un indicateur booléen permettant de déterminer si la voiture est
présente dans la liste.

4°/ Écrire une procédure qui prend entrée un vecteur de n voitures et une
nouvelle voiture et procède à l’insertion de la nouvelle voiture dans la liste ; le
vecteur de sortie devant être trié sur les numéros. La procédure retourne
également un indicateur booléen permettant de déterminer si l’insertion a
effectivement eu lieu.

5°/ Écrire une procédure qui prend entrée un vecteur de n voitures et un numéro
et procède à la suppression de la voiture de numéro demandé. La procédure
retourne également un indicateur booléen permettant de déterminer si la
suppression a effectivement eu lieu.

6°/ Écrire une procédure qui reçoit en entrée un vecteur de n voitures et


procède au tri du vecteur par ordre alphabétique sur les marques, et à marque
égale, sur les prix décroissants.

Librairie

On souhaite gérer les ouvrages vendus dans une librairie à l’aide d’une structure
composée d’un vecteur liste[1..taillemax]. Chaque composante du vecteur est une
variable article composé des champs suivants : le nom de l’auteur, le titre de
l’ouvrage, la discipline, le nom de l’éditeur, l’année d’édition et le prix du livre.

Le vecteur des ouvrages est supposé trié par ordre alphabétique sur les noms
des auteurs.

Les déclarations de types utilisées seront les suivantes :

constante
taillemax = 100 ;
type
touvrage = article
auteur : chaîne ;

12
0 Dr Ndi Nyoungui André
Algorithmique et structures de données

titre : chaîne ;
discipline : chaîne ;
éditeur : chaîne ;
prix : réel ;
quantité : entier ;
fin ;
vouvrage = vecteur[1..taillemax] de touvrage ;

On supposera que les titres de tous les livres écrits par un même auteur sont
différents.

1°/ Écrire une procédure qui crée un vecteur de n livres et le trie par ordre
alphabétique sur les noms des auteurs.

2°/ Écrire une procédure qui imprime un vecteur de n livres.

3°/ Écrire une fonction qui déterminer si un auteur de nom donné a écrit au
moins un livre.

4°/ Écrire une fonction qui délivre l’indice d’un ouvrage de titre et d’auteur
donnés dans la liste si cet ouvrage se trouve dans la liste et 0 sinon.

5°/ Écrire une fonction qui délivre la quantité en stock d’un ouvrage de titre et
d’auteur donnés.

6°/ Écrire une procédure qui imprime la liste des ouvrages dont la quantité en
stock est égale à zéro.

7°/ Écrire une procédure qui imprime la liste des ouvrages édités par un éditeur
donné.

8°/ Écrire une procédure qui imprime la liste des ouvrages disponibles dans une
discipline donnée.

9°/ Écrire une procédure qui ajoute un nouvel ouvrage dans la liste.

10°/ Écrire une procédure qui supprime un ouvrage de titre et d’auteur donnés.

12°/ Écrire une procédure qui supprime tous les livres dont la quantité en stock
est nulle.

12
1 Dr Ndi Nyoungui André
Algorithmique et structures de données

Chapitre 7

Les fichiers séquentiels

Exercice 7.1
Écrire une fonction qui délivre la somme des éléments de rang impair d’un fichier
de nombres entiers.

Première version

L’algorithme est le suivant :


fonction sommeimpairs(nomfichier : chaîne) : entier ;
variable
nombre, somme : entier ;
f : fichier de télément ;
début
relire(f, nomfichier) ;
somme ← 0 ;
tantque non fin(f) faire
début
lire(f, nombre) ;
somme ← somme + nombre ;
si non fin(f) alors
lire(f, nombre) ;
fin ;
sommeimpairs ← somme ;
fermer(f) ;
fin ;

Deuxième version

L’algorithme est le suivant :


fonction sommeimpairs(nomfichier : chaîne) : entier ;
variable
nombre, somme : entier ;
bascule : booléen ;
f : fichier de télément ;

12
2 Dr Ndi Nyoungui André
Algorithmique et structures de données

début
relire(f, nomfichier) ;
somme ← 0 ;
bascule ← vrai ;
tantque non fin(f) faire
début
lire(f, nombre) ;
si bascule alors
somme ← somme + nombre ;

bascule ← non bascule ;


fin ;
sommeimpairs ← somme ;
fermer(f) ;
fin ;

Exercice 7.2
Écrire une fonction qui délivre la différence entre la somme des éléments de
rang pair et la somme des éléments de rang impair d’un fichier de nombres réels.

L’algorithme est le suivant :


fonction diffpairsimpairs(nomfichier : chaîne) : réel ;
variable
nombre, somme : entier ;
f : fichier de télément ;
début
relire(f, nomfichier) ;
somme ← 0 ;
tantque non fin(f) faire
début
lire(f, nombre) ;
somme ← somme - nombre ;
si non fin(f) alors
début
lire(f, nombre) ;
somme ← somme + nombre ;
fin ;
fin ;
diffpairsimpairs ← somme ;
fermer(f) ;
fin ;

12
3 Dr Ndi Nyoungui André
Algorithmique et structures de données

L’algorithme est le suivant :


fonction diffpairsimpairs(nomfichier : chaîne) : réel ;
variable
nombre, somme : entier ;
bascule : booléen ;
f : fichier de télément ;
début
relire(f, nomfichier) ;
somme ← 0 ;
bascule ← vrai ;
tantque non fin(f) faire
début
lire(f, nombre) ;
si bascule alors
somme ← somme - nombre
si non
somme ← somme + nombre ;

bascule ← non bascule;


fin ;
fin ;
diffpairsimpairs ← somme ;
fermer(f) ;
fin ;

Exercice 7.3
Écrire une fonction qui délivre la valeur du dernier élément d’un fichier

L’algorithme est le suivant :


fonction dernier(nomfichier : chaîne) : télément ;
variable
élément : télément ;
f : fichier de télément ;
début
relire(f, nomfichier) ;
tantque non fin(f) faire
lire(f, élément) ;

dernier ← élément ;
fermer(f) ;
fin ;

12
4 Dr Ndi Nyoungui André
Algorithmique et structures de données

Exercice 7.4
Écrire une fonction qui délivre la somme du premier élément et du dernier
élément d’un fichier de nombres réels (par convention, si le fichier est vide la
somme est nulle et si le fichier ne contient qu’un seul élément, la somme est
égale au double de l’unique élément).

L’algorithme est le suivant :


fonction sommeprdr(nomfichier : chaîne) : réel ;
variable
premier, dernier : réel ;
f : fichier de télément ;
début
relire(f, nomfichier) ;
si fin(f) alors
sommeprdr ← 0
sinon
début
lire(f, premier) ;
dernier premier ;
tantque non fin(f) faire
lire(f, dernier) ;

sommeprdr ← premier + dernier ;


fin ;
fermer(f) ;
fin ;

Exercice 7.5
Écrire une fonction qui calcule le nombre d’occurrences d’une valeur dans un
fichier.

L’algorithme est le suivant :


fonction effectifval(nomfichier : chaîne ; val : télément) : entier ;
variable
élément : télément ;
n : entier ;
f : fichier de télément ;
début
relire(f, nomfichier) ;
n←0;
tantque non fin(f) faire
début
12
5 Dr Ndi Nyoungui André
Algorithmique et structures de données

lire(f, élément) ;
si élément = val alors
n←n+1;
fin ;

nboccurrence ← n ;
fermer(f) ;
fin ;

Exercice 7.6
Écrire une fonction qui calcule le rang de la dernière occurrence d’une valeur
dans un fichier.

L’algorithme est le suivant :


fonction rangdernier(nomfichier : chaîne ; val : télément) : entier ;
variable
élément : télément ;
rang, i : entier ;
f : fichier de télément ;
début
relire(f, nomfichier) ;
rang ← 0 ;
i←1;
tantque non fin(f) faire
début
lire(f, élément) ;
si élément = val alors
rang ← i ;
i←i+1;
fin ;

rangdernier ← rang ;
fermer(f) ;
fin ;

Exercice 7.7
Écrire une fonction qui vérifie qu’un fichier contient au moins n éléments.

L’algorithme est le suivant :


fonction aumoinsn(nomfichier : chaîne ; n : entier) : booléen ;
variable
élément : télément ;

12
6 Dr Ndi Nyoungui André
Algorithmique et structures de données

i : entier ;
f : fichier de télément ;
début
relire(f, nomfichier) ;
i←0;
tantque (i < n) et non fin(f) faire
début
lire(f, élément) ;
i←i+1;
fin ;

aumoinsn ← i = n ;
fermer(f) ;
fin ;

Exercice 7.8
Écrire une fonction qui calcule le nombre d’occurrences d’une valeur comprises
entre le ième et le jème éléments avec i < j.

L’algorithme est le suivant :


fonction entreij(nomfichier : chaîne ; val : télément, i, j : entier) : entier ;
variable
élément : télément ;
k : entier ;
f : fichier de télément ;
début
n ← longueur(nomfichier) ;
si (i dans [1..n]) et (j dans [1..n]) et (i ≤ j) alors
début
relire(f, nomfichier) ;
k←1;
tantque (k < i) et non fin(f) faire
début
lire(f, élément) ;
k←k+1;
fin ;

total ← 0 ;
tantque (k ≤ j) et non fin(f) faire
début
lire(f, élément) ;
k←k+1;

12
7 Dr Ndi Nyoungui André
Algorithmique et structures de données

si élément = val
total ← total + 1 ;
fin ;

entreij ← total ;
fermer(f) ;
fin ;
sinon
entreij ← 0 ;
fin ;

Exercice 7.9
Écrire une fonction qui délivre le rang de la première occurrence de la valeur val
dans un fichier. Cette fonction retourne la valeur zéro si la valeur n’est pas
présente dans le fichier.

L’algorithme est le suivant :


fonction rangpremier(nomfichier : chaîne ; val : télément) : booléen ;
variable
élément : télément ;
i : entier ;
f : fichier de télément;
début
relire(f, nomfichier) ;
si fin(f) alors
rangpremier ← 0
sinon
début
lire(f, élément) ;
i←1;
tantque (élément ≠ val) et non fin(f) faire
début
lire(f, élément) ;
i←i+1;
fin ;
si élément = val alors

rangpremier ← i
sinon
rangpremier ← 0
fin ;
fermer(f) ;

12
8 Dr Ndi Nyoungui André
Algorithmique et structures de données

fin ;

Exercice 7.10
Écrire une fonction qui délivre le nombre d’occurrences de la valeur « val1 »
entre les premières occurrences des valeurs « val2 » et « val3 » dans cet ordre.

Première version

fonction effectifval1(nomfichier : chaîne ; val1, val2, val3 : télément) : entier ;


variable
n : entier ;
bval2 : booléen ;
courant : télément ;
f : fichier de télément ;
début
relire(f, nomfichier) ;
n←0;
bval2 ← faux ;
si non fin(f) alors
début
lire(f, courant) ;
tantque non fin(f) et (courant ≠ val3) faire
début
si bval2 et (courant = val1) alors
n←n+1
sinon
si courant = val2 alors
bval2 ← vrai ;
lire(f, courant) ;
fin ;
si bval2 et (courant = val1) alors
n←n+1;
fin ;
effectifval1 ← n ;
fin ;

Deuxième version

On décompose le fichier f en :
f = f1 || <val2> || f2 || <val3> || f3 avec va2 ∉ f1 et val3 ∉ f2.

L’algorithme de divise alors en deux étapes :


12
9 Dr Ndi Nyoungui André
Algorithmique et structures de données

• parcourir du sous-fichier f1,


• compter le nombre d’occurrences de val1 dans le sous-fichier f2.

L’algorithme est alors le suivant :


fonction effectifval1(nomfichier : chaîne ; val1, val2, val3 : télément) : entier ;
variable
n : entier ;
courant : télément ;
f : fichier de télément ;
début
relire(f, nomfichier) ;
n←0;
si non fin(f) alors
début
lire(f, courant) ;
tantque non fin(f) et (courant ≠ val2) faire
lire(f, courant) ;
si courant = val2 alors
début
tantque non fin(f) et (courant ≠ val3) faire
début
lire(f, courant) ;
si courant = val1 alors
n←n+1;
fin ;
fin ;
fin ;
effectifval1 ← n ;
fin ;

Exercice 7.11
On considère un fichier dont le type des éléments est défini par :

type
tpersonne = article
nom : chaîne ;
matricule : chaîne ;
âge : entier ;
sexe : (féminin, masculin) ;
fin ;

13
0 Dr Ndi Nyoungui André
Algorithmique et structures de données

1. Écrire une fonction qui prend en entrée un fichier et délivre l’âge moyen
des femmes présentes dans le fichier.
2. Écrire une procédure qui prend en entrée un fichier et délivre le nombre
d’hommes et le nombre de femmes présents dans le fichier.
3. Écrire une fonction qui prend en entrée un fichier et retourne le nombre
de personnes mineures (moins de 18 ans) présentes dans le fichier.
4. Écrire une fonction qui prend en entrée un fichier et retourne le nom de la
personne la plus âgée présente dans le fichier. On suppose que la personne
la plus âgée est unique.
5. Écrire une procédure qui prend en entrée un fichier et une chaîne de
caractères représentant le matricule d’un employé et détermine si un
employé ayant ce matricule est présent dans la fichier. Dans le cas où
l’employé est présent dans le fichier, la procédure doit aussi retourner
l’ensemble des informations concernant cet employé.

fonction âgemoyen(nomfichier : chaîne) : réel ;


variable
f : fichier de tpersonne ;
pers : tpersonne ;
somme : réel ;
compteur : entier ;
début
relire(f, nomfichier) ;
somme ← 0 ;
compteur ← 0 ;
tantque non fin(f) faire
début
lire(f, pers) ;
somme ← somme + pers.âge ;
compteur ← compteur + 1 ;
fin ;
si compteur = 0 alors
âgemoyen ← 0
sinon
âgemoyen ← somme/compteur ;
fermer(f) ;
fin ;

procédure distribution(nomfichier : chaîne ; var nbhom, ndfem : entier) ;


variable
f : fichier de tpersonne ;

13
1 Dr Ndi Nyoungui André
Algorithmique et structures de données

pers : tpersonne ;
i, j : entier ;
début
relire(f, nomfichier) ;
i←0;
j←0;
tantque non fin(f) faire
début
lire(f, pers) ;
si pers.sexe = masculin alors
i←i+1
sinon
j←j+1;
fin ;
nbhom ← i ;
nbfem ← j ;
fermer(f) ;
fin ;

fonction mineurs(nomfichier : chaîne) : entier ;


variable
f : fichier de tpersonne ;
pers : tpersonne ;
compteur : entier ;
début
relire(f, nomfichier) ;
compteur ← 0 ;
tantque non fin(f) faire
début
lire(f, pers) ;
si pers.âge < 18 alors
compteur ← compteur + 1 ;
fin ;
mineurs ← compteur ;
fermer(f) ;
fin ;

fonction plusâgé(nomfichier : chaîne) : chaîne ;


variable
f : fichier de tpersonne ;
pers : tpersonne ;

13
2 Dr Ndi Nyoungui André
Algorithmique et structures de données

âgegrand : entier ;
nomgrand : chaîne ;
début
relire(f, nomfichier) ;
si fin(f) alors
plusâgé ← ‘*’
sinon
début
lire(f, pers) ;
âgegrand pers.âge ;
nomgrand pers.nom ;
tantque non fin(f) faire
début
lire(f, pers) ;
si pers.âge > grand alors
début
âgegrand ← pers.âge ;
nomgrand ← pers.nom ;
fin ;
fin ;
plusâgé ← nomgrand ;
fin ;
fermer(f) ;
fin ;

procédure recherche(nomfichier : chaîne ; numéro : chaîne ;


var elem : tpersonne ; var trouvé : booléen) ;
variable
f : fichier de tpersonne ;
pers : tpersonne ;
début
relire(f, nomfichier) ;
trouvé ← faux ;
tantque non fin(f) et (non trouvé) faire
début
lire(f, pers) ;
si pers.matricule = numéro alors
début
trouvé ← vrai;
elem ← pers ;
fin ;

13
3 Dr Ndi Nyoungui André
Algorithmique et structures de données

fin;
fermer(f) ;
fin ;

Exercice 7.12
Écrire une fonction qui reçoit en entrée un fichier et vérifie que le fichier est
trié dans l’ordre croissant sans répétition.

Le raisonnement et l’algorithme sont semblables à ceux du cours pour les fichiers


triés.

L’algorithme est le suivant :


fonction fichiertriésr(nomfichier : chaîne) : booléen ;
variable
courant, précédent : télément ;
f : fichier de télément ;
début
relire(f, nomfichier) ;
si fin(f) alors
fichiertriésr ← vrai
sinon
début
lire(f, précédent) ;
si fin(f) alors
fichiertriésr ← vrai
sinon
début
lire(f, courant)
tantque non fin(f) et (précédent < courant) faire
début
précédent ← courant ;
lire(f, courant) ;
fin ;
fichiertriésr ← précédent < courant ;
fin ;
fin,
fermer(f) ;
fin ;

Exercice 7.13

13
4 Dr Ndi Nyoungui André
Algorithmique et structures de données

Écrire une fonction qui reçoit en entrée un fichier et vérifie que le fichier est
trié dans l’ordre décroissant.

Il s’agit du même algorithme que celui du cours (fichier trié par ordre croissant)
mais en inversant la relation d’ordre ; il faut alors inverser les tests entre les
variables précédent et courant.

L’algorithme est alors le suivant :


fonction fichiertriédec(nomfichier : chaîne) : booléen ;
variable
courant, précédent : télément ;
f : fichier de télément ;
début
relire(f, nomfichier) ;
si fin(f) alors
fichiertriédec ← vrai
sinon
début
lire(f, précédent) ;
si fin(f) alors
fichiertriédec ← vrai
sinon
début
lire(f, courant) ;
tantque non fin(f) et (précédent ≥ courant) faire
début
précédent ← courant ;
lire(f, courant) ;
fin ;
fichiertriédec ← précédent ≥ courant ;
fin ;
fin ;
fermer(f) ;
fin ;

Exercice 7.14
Écrire un algorithme qui délivre le nombre d’occurrences de la valeur val dans un
fichier trié.

L’algorithme est le suivant :


fonction effectifval(nomfichier : chaîne ; val : télément) : entier ;

13
5 Dr Ndi Nyoungui André
Algorithmique et structures de données

variable
nb : entier ;
f : fichier de télément ;
courant : télément ;
début
relire(f, nomfichier) ;
nb ← 0 ;
si non fin(f) alors
début
lire(f, courant) ;
tantque non fin(f) et (courant ≤ val) faire
début
si courant = val alors
nb ← nb + 1 ;
lire(f, courant) ;
fin ;
si courant = val alors
nb ← nb + 1 ;
fin ;
effectifval nb ;
fin ;

Deuxième version

L’algorithme est le suivant :


fonction effectifval(nomfichier : chaîne ; val : télément) : entier ;
variable
nb : entier ;
f : fichier de ELEMENT ;
courant : télément ;
début
relire(f, nomfichier) ;
nb ← 0 ;
si non fin(f) alors
début
lire(f, courant) ;
tantque non fin(f) et (courant < val) faire
lire(f, courant) ;

tantque non fin(f) et (courant = val) faire


début

13
6 Dr Ndi Nyoungui André
Algorithmique et structures de données

nb ← nb + 1 ;
lire(f, courant) ;
fin ;
si courant = val alors
nb ← nb + 1 ;
fin ;
effectifval nb ;
fin ;

Exercice 7.15
Écrire un algorithme qui délivre le rang de la dernière occurrence de la valeur val
dans un fichier trié ou zéro si val ne se trouve pas dans le fichier.

On peut deviser le fichier en deux sous-fichiers tels que :


• le premier composé des éléments inférieurs ou égaux à val,
• le deuxième composé des éléments supérieurs à val.

ou en trois fichiers tels que :


• le premier composé des éléments inférieurs à val,
• le deuxième composé des occurrences de la valeur val,
• le troisième composé des éléments supérieurs à val.

Nous pouvons proposer deux versions de l’algorithme.

Première version

L’algorithme consiste à parcourir le premier sous-fichier en comptant ses


éléments dans une variable de contrôle i. A chaque étape on compare l’élément
courant est à val. Si les deux valeurs sont égales, on met le rang courant r à i.
Comme le dernier élément lu n’est pas comparé à val dans la boucle, on regarde à
la sortie de la boucle si le dernier élément lu est égal à val pour repositionner r.

L’algorithme est alors le suivant :


fonction rangderval(nomfichier : chaîne ; val : télément) : entier ;
variable
r, i : entier ;
courant: télément;
f: fichier de télément;
début
relire(f, nomfichier);
i←1;

13
7 Dr Ndi Nyoungui André
Algorithmique et structures de données

r←0;
si non fin(f) alors
début
lire(f, courant) ;
tantque non fin(f) et( courant ≤ val) faire
début
si courant = val alors
r←i;
i←i+1;
lire(f, courant) ;
fin ;
si courant = val alors
r←i;
fin ;
rangderval ← r ;
fermer(f) ;
fin ;

Deuxième version

L’algorithme consiste à parcourir le premier sous-fichier, puis le deuxième sous-


fichier en comptant leurs éléments dans une variable de contrôle i. A la fin du
parcours, on compare le dernier élément lu à val. Si les deux valeurs sont égales,
on affecte la valeur vde i à r.

L’algorithme est alors le suivant :


fonction rangderval(nomfichier : chaîne ; val : télément) : entier ;
variable
r, i : entier ;
courant: télément;
f: fichier de télément;
début
relire(f, nomfichier);
i←1;
r←0;
si non fin(f) alors
début
lire(f, courant) ;
tantque non fin(f) et( courant < val) faire
début
lire(f, courant) ;

13
8 Dr Ndi Nyoungui André
Algorithmique et structures de données

i←i+1;
fin ;
tantque non fin(f) et( courant = val) faire
début
r←i;
lire(f, courant) ;
i←i+1;
fin ;
si courant = val alors
r←i;
fin;
rangderval ← r ;
fermer(f);
fin ;

Exercice 7.16
Écrire un algorithme qui recherche la valeur val après le rang i dans un fichier
trié.

Première version

L’algorithme est le suivant :


fonction rechercheaprèsi(nomfichier : chaîne ; i : entier ; val : télément) :
booléen ;
variable
j : entier ;
courant : télément ;
f : fichier de télément ;
début
relire(f, nomfichier) ;
j←0;
tantque non fin(f) et (j ≤ i) faire
debut
lire(f, courant) ;
j←j+1;
fin ;
si j ≠ i + 1 alors
rechercheaprèsi ← faux
sinon
si courant = val alors
rechercheaprèsi ← vrai

13
9 Dr Ndi Nyoungui André
Algorithmique et structures de données

sinon
si courant > val alors
rechercheaprèsi ← faux
sinon
début
tantque non fin(f) et (courant < val) faire
lire(f, courant) ;
rechercheaprèsi ← courant = val ;
fin ;
fin ;

Deuxième version

L’algorithme est le suivant :


fonction rechercheaprèsi(nomfichier : chaîne ; i : entier ; val : télément) :
booléen ;
variable
j : entier ;
courant : télément ;
f : fichier de télément ;
début
relire(f, nomfichier) ;
rechercheaprèsi ← faux ;
si non fin(f) alors
début
lire(f, courant) ;
j←1;
tantque non fin(f) et (j ≤ i) et (courant ≤ val) faire
debut
lire(f, courant) ;
j←j+1;
fin ;
tantque non fin(f) et (courant < val) faire
lire(f, courant) ;

rechercheaprèsi ← (courant = val) et ( j > i) ;


fin ;
fin ;

Exercice 7.17

14
0 Dr Ndi Nyoungui André
Algorithmique et structures de données

Écrire une procédure qui prend en entrée un fichier de nombres entiers et


délivre en sortie deux fichiers, le premier contenant les nombres pairs et le
deuxième les nombres impairs.

L’algorithme est le suivant :


procédure pairsimpairs(nomfichier, pairs, impairs : chaîne) ;
variable
f, g, h : fichier de entier ;
nombre : entier ;
début
relire(f, nomfichier) ;
réécrire(g, pairs) ;
réécrire(h, impairs) ;
tantque non fin(f) faire
début
lire(f, nombre) ;
si pair(nombre) alors
écrire(g, nombre)
sinon
écrire(h, nombre) ;
fin ;
fermer(f) ;
fermer(g) ;
fermer(h) ;
fin ;

Exercice 7.18
Écrire une procédure qui prend en entrée un fichier de nombres entiers et
délivre en sortie deux fichiers, le premier contenant les éléments de rang impair
et le deuxième les éléments de rang pair.

L’algorithme est le suivant :


procédure éclater(origine, pairs, impairs : chaîne) ;
variable
courant : télément ;
bascule : booléen ;
f, g, h : fichier de télément ;
début
relire(f, origine) ;
réécrire(g, pairs) ;
réécrire(h, impairs) ;

14
1 Dr Ndi Nyoungui André
Algorithmique et structures de données

bascule ← faux ;
tantque non fin(f) faire
début
lire(f, courant) ;
si bascule alors
écrire(h, courant)
sinon
écrire(g, courant) ;
bascule ← non bascule ;
fin ;
fermer(f) ;
fermer(g) ;
fermer(h) ;
fin ;

Exercice 7.19
Écrire une procédure d’union de deux fichiers triés par ordre croissant sans
répétition (le fichier obtenu doit être trié sans répétition).

Appelons fH et gH et hH les fichiers f, g et h munis d’une « high-value » H.

L’algorithme est le suivant :


procédure union(source1, source2, sortie : chaîne);
variable
cf, cg: télément;
fH, gH, hH: fichier de télément;
début
relire(fH, source1) ;
relire(gH, source2) ;
réécrire(gH, sortie) ;
lire(fH, cf) ;
lire(gH, cg) ;
tantque non fin(fH) ou non fin(gH) faire
si cf < cg alors
début
écrire(hH, cf) ;
lire(fH, cf) ;
fin
sinon
si cf > cg alors
début

14
2 Dr Ndi Nyoungui André
Algorithmique et structures de données

écrire(hH, cg) ;
lire(gH, cg) ;
fin
sinon
début
écrire(hH, cf) ;
lire(fH, cf) ;
lire(gH, cg) ;
fin ;
écrire(hH, cf) ;
fermer(fH) ;
fermer(gH) ;
fermer(hH) ;
fin ;

Exercice 7.20
Écrire une procédure d’intersection de deux fichiers triés par ordre croissant
sans répétition (le fichier obtenu doit être trié sans répétition).

L’algorithme est le suivant :


procédure intersection(source1, source2, sortie : chaîne);
variable
cf, cg: télément;
fH, gH, hH: fichier de télément;
début
relire(fH, source1) ;
relire(gH, source2) ;
réécrire(gH, sortie) ;
lire(fH, cf) ;
lire(gH, cg) ;
tantque non fin(fH) et non fin(gH) faire
si cf < cg alors
lire(fH, cf) ;
sinon
si cf > cg alors
lire(gH, cg) ;
sinon
début
écrire(hH, cf) ;
lire(fH, cf) ;
lire(gH, cg) ;

14
3 Dr Ndi Nyoungui André
Algorithmique et structures de données

fin ;
si fin(f) alors
écrire(hH, cf)
sinon
écrire(hH, cg) ;
fermer(fH) ;
fermer(gH) ;
fermer(hH) ;
fin ;

Exercice 7.21
Écrire une procédure d’insertion de la valeur elem après chaque occurrence de la
valeur val dans un fichier.

L’algorithme est le suivant :


procédure insertoutes(source, sortie : chaîne ; val, elem : télément) ;
variable
courant : télément ;
f, g : fichier de télément ;
début
relire(f, source) ;
réécrire(g, sortie) ;
tantque non fin(f) faire
début
lire(f, courant) ;
écrire(g, courant) ;
si courant = val alors
écrire(g, elem) ;
fin ;
fermer(f) ;
fermer(g) ;
fin ;

Exercice 7.22
Écrire une procédure d’insertion de la valeur elem après la dernière occurrence
de la valeur val dans un fichier trié.

L’algorithme est le suivant :


procédure inserdernier(source, sortie : chaîne ; val, elem : télément ;
var possible :
booléen) ;

14
4 Dr Ndi Nyoungui André
Algorithmique et structures de données

variable
courant : télément ;
f, g : fichier de télément ;
trouvé : booléen ;
début
relire(f, source) ;
réécrire(g, sortie) ;
trouvé ← faux ;
si non fin(f) alors
début
lire(f, courant) ;
tantque non fin(f) et (courant ≤ val) faire
début
écrire(g, courant) ;
trouvé ← courant = val ;
lire(f, courant) ;
fin ;
si courant = val alors
début
écrire(g, courant) ;
écrire(g, elem) ;
trouvé ← vrai ;
fin
sinon
si trouvé alors
début
écrire(g, elem) ;
écrire(g, courant) ;
tantque non fin(f) faire
début
lire(f, courant) ;
écrire(g, courant) ;
fin ;
fin ;
fin ;
fermer(f) ;
fermer(g) ;
fin ;

Exercice 7.23

14
5 Dr Ndi Nyoungui André
Algorithmique et structures de données

Écrire une procédure de suppression, dans un fichier, de tous les éléments ayant
un rang compris entre i et j (j ≥ i).

Première version

L’algorithme est le suivant :


procédure supprimeij(source, sortie : chaîne ; i, j : entier ; var possible :
booléen) ;
variable
k : entier ;
courant : télément ;
f, g : fichier de télément ;
début
relire(f, source) ;
réécrire(g, sortie) ;
k←1;
tantque non fin(f) et (k < i) faire
début
lire(f, courant) ;
écrire(g, courant) ;
k←k+1;
fin ;
tantque non fin(f) et (k ≤ j) faire
début
lire(f, courant) ;
k←k+1;
fin ;
si k = j + 1 alors
début
possible ← vrai
tantque non fin(f) faire
début
lire(f, courant) ;
écrire(g, courant) ;
fin ;
fin
sinon
possible ← faux ;
fermer(f) ;
fermer(g) ;
fin ;

14
6 Dr Ndi Nyoungui André
Algorithmique et structures de données

Deuxième version

L’algorithme est le suivant :


procédure supprimeij(source, sortie : chaîne ; i, j : entier ; var possible :
booléen) ;
variable
k : entier ;
courant : télément ;
f, g : fichier de télément ;
début
relire(f, source) ;
réécrire(g, sortie) ;
k←1;
tantque non fin(f) faire
début
lire(f, courant) ;
si (k < i) ou (k > j) alors
écrire(g, courant) ;
k←k+1;
fin ;
possible ← k > j ;
fermer(f) ;
fermer(g) ;
fin ;

Exercice 7.24
Écrire une procédure de suppression de toutes les occurrences de la valeur val
dans un fichier trié.

L’algorithme est le suivant :


procédure supptoutes(source, sortie : chaîne ; val : télément ; var possible :
booléen) ;
variable
courant : télément ;
f, g : fichier de télément ;
début
relire(f, source) ;
réécrire(g, sortie) ;
possible ← faux
si non fin(f) alors

14
7 Dr Ndi Nyoungui André
Algorithmique et structures de données

début
lire(f, courant) ;
tantque non fin(f) et (courant < val) faire
début
écrire(g, courant) ;
lire(f, courant) ;
fin ;
si courant > val alors
possible ← faux
sinon
début
possible ← vrai ;
tantque non fin(f) et (courant = val) faire
lire(f, courant) ;
si courant > val alors
début
écrire(g, courant) ;
tantque non fin(f) faire
début
lire(f, courant) ;
écrire(g, courant) ;
fin ;
fin ;
fin ;
fin ;
fermer(f) ;
fermer(g) ;
fin ;

Deuxième version

L’algorithme est le suivant :


procédure supptoutes(source, sortie : chaîne ; val : télément ; var possible :
booléen) ;
variable
courant : télément ;
f, g : fichier de télément ;
trouvé, stop : booléen ;
début
relire(f, source) ;
réécrire(g, sortie) ;

14
8 Dr Ndi Nyoungui André
Algorithmique et structures de données

trouvé ← faux ;
stop ← faux ;
tantque non fin(f) et non stop alors
début
lire(f, courant) ;
si (courant < val) alors
écrire(g, courant) ;
sinon
si courant = val alors
trouvé ← vrai
sinon
si trouvé alors
écrire(g, courant)
sinon
stop ← vrai ;
fin ;
possible ← trouvé ;
fermer(f) ;
fermer(g) ;
fin ;

Exercice 7.25
Écrire une procédure de suppression de tous les espaces (caractère blanc)
superflus dans une fichier de caractères. Le fichier résultat ne doit jamais
contenir deux espaces consécutifs.

L’algorithme est le suivant :


procédure suppespace(source, sortie : chaîne) ;
constante
Blank = ' ' ;
variable
courant, précédent : caractère ;
f, g : fichier de caractère ;
début
relire(f, source) ;
réécrire(g, sortie) ;
précédent ← Blank ;
tantque non fin(f) faire
début
lire(courant) ;
si (courant ≠ Blank) ou (précédent ≠ Blank) alors

14
9 Dr Ndi Nyoungui André
Algorithmique et structures de données

écrire(g, courant) ;
précédent ← courant ;
fin ;
fermer(f) ;
fermer(g) ;
fin ;

Exercice 7.26
On considère un fichier d’étudiants dont le type des éléments est défini par :

type
toption = (GBIO, MIP, GTE, GIN) ;
tétudiant = article
nom : chaîne ;
matricule : chaîne ;
option : toption ;
fin ;

1. Écrire une procédure qui prend en entrée un fichier d’étudiants et


supprime tous les étudiants d’une filière donnée.
2. Écrire une procédure qui prend en entrée un fichier d’étudiants, une
chaîne de caractères représentant le matricule d’un étudiant et supprime
l’étudiant qui possède ce matricule.

On suppose maintenant que le fichier est trié par rapport à l’option.

3. Écrire une procédure qui prend en entrée un fichier d’étudiants et


supprime tous les étudiants d’une filière donnée.

Suppression de tous les étudiants d’une filière

procédure suppoption(source, sortie : chaîne ; option : toption ; var possible :


booléen) ;
variable
étudiant : tétudiant ;
f, g : fichier de tétudiant ;
début
relire(f, source) ;
réécrire(g, sortie) ;
possible ← faux ;
tantque non fin(f) faire
début

15
0 Dr Ndi Nyoungui André
Algorithmique et structures de données

lire(f, étudiant) ;
si étudiant.option = option alors
possible ← vrai
sinon
écrire(g, étudiant) ;
fin ;
fermer(f) ;
fermer(g) ;
fin ;

Suppression selon le matricule

procédure suppmatricule(source, sortie : chaîne ; matricule : chaîne ; var trouvé :


booléen) ;
variable
étudiant : tétudiant ;
f, g : fichier de tétudiant ;
début
relire(f, source) ;
réécrire(g, sortie) ;
trouvé ← faux ;
tantque non fin(f) faire
début
lire(f, étudiant) ;
si étudiant.matricule = matricule alors
trouvé ← vrai
sinon
écrire(g, étudiant) ;
fin ;
fermer(f) ;
fermer(g) ;
fin ;

Suppression dans un fichier trié

procédure suppoption(source, sortie : chaîne ; option : toption ; var possible :


booléen) ;
variable
étudiant : tétudiant ;
f, g : fichier de tétudiant ;
trouvé, stop : booléen ;

15
1 Dr Ndi Nyoungui André
Algorithmique et structures de données

début
relire(f, source) ;
réécrire(g, sortie) ;
trouvé ← faux ;
stop ← faux ;
tantque non fin(f) et non stop alors
début
lire(f, étudiant) ;
si (étudiant.option < option) alors
écrire(g, étudiant) ;
sinon
si étudiant.option = option alors
trouvé ← vrai
sinon
si trouvé alors
écrire(g, étudiant)
sinon
stop ← vrai ;
fin ;
possible ← trouvé ;
fermer(f) ;
fermer(g) ;
fin ;

Études de cas

Dans ce chapitre, nous appliquerons les algorithmes sur les fichiers séquentiels
composés d’articles ayant une structure complexe : gestion d’un fichier du
personnel enseignant d’une faculté (comptage des éléments vérifiant une ou
plusieurs propriétés, recherche d’éléments vérifiant une ou plusieurs propriétés,
mise à jour de fichiers, éclatement de fichiers), la facturation des bons de
commandes (comptage, création de fichiers, mise à jour, édition de factures), la
gestion académique des étudiants ‘une faculté.

Gestion des étudiants

On veut écrire un programme pour générer les étudiants inscrits dans une
faculté. Les informations sur les étudiants sont stockés dans un fichier. Les
informations retenues pour chaque étudiant sont : le numéro matricule
(différent pour chaque étudiant), le nom, le sexe, le programme de formation de
la filière concernée.

15
2 Dr Ndi Nyoungui André
Algorithmique et structures de données

On disposera des définitions de types suivantes :

constante
nbmax = 40 ;
type
tcours = article
Code : chaîne ;
Intitulé : chaîne ;
Note : réel ;
fin ;
vcours = vecteur[1..nbmax] de tcours ;
tfilière = article
Code : chaîne ;
Dénomination : chaîne ;
nbcours : entier ;
listecours : vcours ;
fin ;
tétudiant = article
Matricule : chaîne ;
Nom : chaîne ;
Sexe : (Féminin, Masculin) ;
filière : tfilière ;
fin ;
fétudiant = fichier de tétudiant ;

On suppose que chaque étudiant a un matricule différent et que tous les


étudiants inscrits dans la même filière ont le même nombre et la même liste de
cours.

1°/ Écrire une procédure qui crée un fichier de n étudiants.

Nous écrivons d’abord une procédure pour lire les informations sur un étudiant.

procédure lireétudiant(var etudiant : tétudiant) ;


variable
i : entier ;
Ch : caractère ;
début
écrire('Matricule : ' ) ;
lire(etudiant.Matricule) ;

15
3 Dr Ndi Nyoungui André
Algorithmique et structures de données

écrire('Nom : ' ) ;
lire(etudiant.Nom) ;
écrire('Sexe (F ou M): ' ) ;
lire(Ch) ;
si Ch = 'F' alors
etudiant.Sexe ← Feminin
sinon
si Ch = 'M' alors
etudiant.Sexe ← Masculin ;
écrire('Code filière : ' ) ;
lire(etudiant.filière.Code) ;
écrire('Dénomination filière : ' ) ;
lire(etudiant.filière.Dénominantion) ;
écrire('Nombre de cours : ' ) ;
lire(etudiant.filière.nbcours) ;
i ←1 ;
tantque i ≤ etudiant.filière.nbcours faire
début
écrire('Code du cours : ' ) ;
lire(etudiant.filière.listecours[i].Code) ;
écrire('Intitulé du cours : ' ) ;
lire(etudiant.filière.listecours[i].Intitulé) ;
écrire('Note obtenue : ' ) ;
lire(etudiant.filière.listecours[i].Note) ;
i←i+1;
fin ;
fin ;

procédure créerfichier(nomfichier : chaîne ; n : entier) ;


variable
étudiant : tétudiant ;
i : entier ;
f : fétudiant ;
début
réécrire(f, nomfichier) ;
i←0;
tantque i < n faire
début
lireétudiant(étudiant) ;
écrire(f, étudiant) ;
i←i+1;

15
4 Dr Ndi Nyoungui André
Algorithmique et structures de données

fin ;
fermer(f) ;
fin ;

2°/ Écrire une procédure qui imprime la liste générale des étudiants inscrits.

Nous écrivons d’abord une procédure pour afficher le nom, le matricule, le sexe
et la filière d’un étudiant.

procédure afficherétudiant(étudiant : tétudiant) ;


variable
i : entier ;
Ch : caractère ;
début
écrire('Matricule : ' , étudiant.Matricule) ;
écrire('Nom : ', étudiant.Nom) ;
si etudiant.Sexe ← Feminin alors
écrire('Sexe : Féminin')
sinon
écrire('Sexe : Masculin') ;
écrire('Filière : ', étudiant.filière.Dénominantion) ;
fin ;

procédure imprimerfichier(nomfichier : chaîne) ;


variable
étudiant : tétudiant ;
f : fétudiant ;
début
relire(f, nomfichier) ;
tantque non(f) faire
début
lire(f, étudiant) ;
afficherétudiant(étudiant) ;
fin ;
fermer(f) ;
fin ;

3°/ Écrire une fonction qui délivre le nombre d’étudiants inscrits dans une filière
de code donné.

fonction nbinscrits(nomfichier : chaîne ; code : chaîne) : entier ;


variable
15
5 Dr Ndi Nyoungui André
Algorithmique et structures de données

étudiant : tétudiant ;
f : fétudiant ;
nb : entier ;
début
relire(f, nomfichier) ;
nb ← 0 ;
tantque non(f) faire
début
lire(f, étudiant) ;
si étudiant.filière.Code = code alors
nb ← nb + 1 ;
fin ;
nbinscrits ← nb ;
fermer(f) ;
fin ;

4°/ Écrire une fonction qui délivre le nombre d’unités de valeurs validée par un
étudiant de matricule donné.

fonction nbvalidés(nomfichier : chaîne ; matricule : chaîne) : entier ;


variable
étudiant : tétudiant ;
f : fétudiant ;
i, nb : entier ;
trouvé: booléen;
début
relire(f, nomfichier) ;
trouvé ← faux ;
tantque non(f) et (non trouvé) faire
début
lire(f, étudiant) ;
si étudiant.matricule = matricule alors
trouvé ←vrai ;
fin ;
nb ← 0 ;
si trouvé alors
début
i←1;
tantque i ≤ étudiant.filière.nbcours faire
début
si étudiant.filière.listecours[i].note ≥ 10 alors

15
6 Dr Ndi Nyoungui André
Algorithmique et structures de données

nb ← nb + 1 ;
i←i+1;
fin ;
fin ;
nbvalidés ← nb ;
fermer(f) ;
fin ;

5°/ Écrire une procédure qui imprime la liste étudiants ayant validé la totalité de
leurs unités de valeurs dans une filière donnée.

procédure listemajors(nomfichier : chaîne) ;


variable
étudiant : tétudiant ;
f : fétudiant ;
i, nb : entier ;
début
relire(f, nomfichier) ;
tantque non(f) faire
début
lire(f, étudiant) ;
i←1;
nb ← 0 ;
tantque i ≤ étudiant.filière.nbcours faire
début
si étudiant.filière.listecours[i].note ≥ 10 alors
nb ← nb + 1 ;
i←i+1;
fin ;
si nb = étudiant.filière.nbcours alors
afficherétudiant(étudiant) ;
fin ;
fermer(f) ;
fin ;

6°/ Écrire une procédure qui imprime (matricule, nom, sexe, filière) de tous les
étudiants présents dans le fichier.

7°/ Écrire une procédure qui imprime la liste des garçons inscrits dans une
filière de code donné.

procédure listefilière(nomfichier : chaîne ; code : chaîne) ;

15
7 Dr Ndi Nyoungui André
Algorithmique et structures de données

variable
étudiant : tétudiant ;
f : fétudiant ;
début
relire(f, nomfichier) ;
tantque non(f) faire
début
lire(f, étudiant) ;
si nb = étudiant.filière.code = code alors
afficherétudiant(étudiant) ;
fin ;
fermer(f) ;
fin ;

8°/ Écrire une procédure qui imprime la liste générale des garçons inscrits.

procédure listegarçons(nomfichier : chaîne) ;


variable
étudiant : tétudiant ;
f : fétudiant ;
début
relire(f, nomfichier) ;
tantque non(f) faire
début
lire(f, étudiant) ;
si étudiant.sexe = Masculin alors
afficherétudiant(étudiant) ;
fin ;
fermer(f) ;
fin ;

9°/ Écrire une procédure qui imprime la liste des filles inscrites dans une filière
de code donné.

procédure listefilles(nomfichier : chaîne ; code : chaîne) ;


variable
étudiant : tétudiant ;
f : fétudiant ;
début
relire(f, nomfichier) ;
tantque non(f) faire
début

15
8 Dr Ndi Nyoungui André
Algorithmique et structures de données

lire(f, étudiant) ;
si (étudiant.sexe = Feminin) et (étudiant.filière.code = code)
alors
afficherétudiant(étudiant) ;
fin ;
fermer(f) ;
fin ;

10°/ Écrire une procédure qui imprime la liste générale des filles inscrites.

11°/ Écrire une procédure qui imprime le relevé des notes d’un étudiant de
matricule donné.

procédure imprimernotes(filename : chaîne ; matricule : chaîne) ;


variable
i : entier ;
étudiant : tétudiant ;
f : fétudiant ;
début
relire(f, filename) ;
trouvé ← faux;
tantque non fin(f) et (non trouvé) faire
début
lire(f, étudiant) ;
si étudiant.matricule = matricule alors
trouvé ← vrai ;
fin ;
si trouvé alors
début
écrire('Matricule : ' , étudiant.Matricule) ;
écrire('Nom : ', étudiant.Nom) ;
écrire('Prénom: ', étudiant.Prénom) ;
si etudiant.Sexe ← Feminin alors
écrire('Sexe : Féminin')
sinon
écrire('Sexe : Masculin') ;
i←1;
tantque i ≤ étudiant.filière.nbcours faire
début
écrire(étudiant.filière.listecours[i].Code) ;
écrire(étudiant.filière.listecours[i].Intitulé) ;
écrire(étudiant.filière.listecours[i].Note) ;

15
9 Dr Ndi Nyoungui André
Algorithmique et structures de données

i←i+1;
fin ;
fin;
fermer(f) ;
fin ;

12°/ Écrire une procédure qui éclate un fichier d’étudiants en deux fichiers
suivant le sexe de l’étudiant.

14°/ Écrire une procédure qui insère un nouvel étudiant dans le fichier.

Aucun critère n’étant précisé, on procède à une insertion en fin de fichier.

procédure suppmatricule(oldname, newname : chaîne ; étudiant : tétudiant) ;


variable
f, g : fétudiant ;
courant: tétudiant;
début
relire(f, oldname) ;
réécrire(g, newname) ;
tantque non(f) faire
début
lire(f, courant) ;
écrire(g, courant) ;
fin ;
écrire(g, étudiant) ;
fermer(f) ;
fermer(g) ;
fin ;

15°/ Écrire une procédure qui supprime le kème élément du fichier.

16/° Écrire une procédure qui supprime un étudiant de matricule donné.

procédure suppmatricule(oldname, newname : chaîne ; matricule : chaîne) ;


variable
étudiant : tétudiant ;
f, g : fétudiant ;
début
relire(f, oldname) ;
réécrire(g, newname) ;
tantque non(f) faire
début
16
0 Dr Ndi Nyoungui André
Algorithmique et structures de données

lire(f, étudiant) ;
si étudiant.matricule ≠ matricule alors
écrire(g, étudiant) ;
fin ;
fermer(f) ;
fermer(g) ;
fin ;

17°/ Écrire une procédure qui supprime tous étudiants d’une filière de code
donné.

procédure supptous(oldname, newname : chaîne ; code : chaîne) ;


variable
étudiant : tétudiant ;
f, g : fétudiant ;
début
relire(f, oldname) ;
réécrire(g, newname) ;
tantque non(f) faire
début
lire(f, étudiant) ;
si étudiant.filière.code ≠ code alors
écrire(g, étudiant) ;
fin ;
fermer(f) ;
fermer(g) ;
fin ;

Personnel enseignant

On veut gérer le fichier du personnel enseignant d’un établissement


universitaire. Pour chaque enseignant les informations retenus sont les
suivantes : matricule, nom (nom et prénoms) ; statut (permanent ou vacataire) ;
grade (Professeur, Maître de Conférences, Chargé de Cours, Assistant) ;
département d’affectation (Mathématiques, Physique, Mécanique, Chimie,
Informatique, …) ; nombre de cours enseignés, nombre d’années d’ancienneté ;
position (présent ou en congé). Le fichier sera trié par ordre croissant sur les
matricules, supposés tous différents.

On disposera des définitions de types suivantes :

16
1 Dr Ndi Nyoungui André
Algorithmique et structures de données

type
tenseignant = article
matricule : entier ;
nom : chaîne ;
statut : chaîne;
département : chaîne;
présent : booléen ;
grade : chaîne;
nbcours : entier;
ancienneté : entier ;
fin ;
fesneignant = fichier de tenseignant ;

1°/ Écrire un algorithme pour créer un fichier d’enseignants.

2°/ Écrire un algorithme pour afficher, le matricule, le nom et le grade de


chacun des enseignants ayant un statut donné et qui sont maintenant en congé.

3°/ Écrire un algorithme pour afficher, le matricule, le nom, le statut, le grade


et la position de chacun des enseignants affectés à un département donné.

4°/ Écrire un algorithme qui délivre le nombre d’enseignants ayant un grade


donné et qui sont actuellement en congé.

5°/ Écrire un algorithme qui délivre le nombre des assistants les plus anciens
ainsi que leur nombre d’années d’ancienneté.

6°/ Écrire un algorithme qui délivre le numéro matricule et le nom du premier


enseignant ayant un grade donné.

7°/ Écrire un algorithme qui retourne le département d’affectation d’un


enseignant de matricule donné.

8°/ Écrire un algorithme qui vérifie qu’une personne de matricule donné est bien
dans le fichier et qu’elle est actuellement en poste. Si ces conditions sont
remplies, un nouveau fichier est créé où cette personne est mise en congé.

9°/ Écrire une procédure pour supprimer un enseignant de matricule donné dans
le fichier des personnels.

10°/ Écrire un algorithme qui éclate le fichier des personnels en deux fichiers :
un contenant les personnels en poste et un autre les personnels en congé.

Solution
16
2 Dr Ndi Nyoungui André
Algorithmique et structures de données

2°/ Écrire un algorithme pour afficher, le matricule, le nom et le grade de


chacun des enseignants ayant un statut donné et qui sont maintenant en congé.

Il s’agit d’un parcours de fichier avec affichage des éléments vérifiant certaines
propriétés.

procédure imprimerfichier(nomfichier : chaîne ; statut : chaîne) ;


variable
enseigant : tenseignant ;
f : fichier de tenseignant ;
début
relire(f, nomfichier) ;
tantque non fin(f) faire
début
lire(f, enseignant) ;
si (enseignant.statut = statut) et (non enseignant.présent)
alors
début
écrireln('Matricule : ' enseignant.matricule) ;
écrireln('Nom : ', enseignant.nom) ;
écrireln('Grade : ', enseignant.grade)
fin ;
fermer(f) ;
fin ;

3°/ Écrire un algorithme pour afficher, le matricule, le nom, le statut, le grade


et la position de chacun des enseignants affectés à un département donné.

Il s’agit d’un parcours de fichier avec affichage des éléments vérifiant une
certaine propriété.

procédure imprimerliste(nomfichier : chaîne ; département : chaîne) ;


variable
enseignant : tenseignant ;
f : fichier de tenseignant ;
début
relire(f, nomfichier) ;
tantque non fin(f) faire
début
lire(f, enseignant) ;
si (enseignant.département = département) alors
16
3 Dr Ndi Nyoungui André
Algorithmique et structures de données

début
écrire('Matricule : ' enseignant.matricule) ;
écrire('Nom : ', enseigant.nom) ;
{écriture du statut}
écrire('Statut :', enseignant.statut)
écrire('Grade : ', enseignant.grade)
si ens.position alors
écrire('Position : Présent')
sinon
écrire('Position : Congé') ;
fin ;
fermer(f) ;
fin ;

4°/ Il s’agit d’une application directe de l’algorithme qui compte le nombre


d’occurrences d’une valeur donnée dans un fichier. Au lieu d’une valeur d’élément,
on s’intéresse ici à un champ de l’article.

fonction nbabsents(nomfichier : chaîne ; grade : chaîne) : entier ;


variable
compte : entier ;
enseignant : tenseignant ;
f : fichier de tenseignant ;
début
relire(f, nomfichier) ;
compte ← 0 ;
tantque non fin(f) faire
début
lire(f, ens) ;
si (enseignant.grade = grade) et (non enseignant.présent)
alors
compte ← compte + 1 ;
fin ;
nbabsents ←compte ;
fermer(f) ;
fin ;

Facturation

On envisage de simuler une application de facturation simplifiée pour une


entreprise de vente de matériels informatiques par Internet.

16
4 Dr Ndi Nyoungui André
Algorithmique et structures de données

Chaque client émet un ou plusieurs bons de commande. À partir de ces bons de


commande, on établit une ou plusieurs factures par client.

Dans un premier temps, on dispose d’un fichier de commandes contenant tous les
bons de commande de l’ensemble des clients.

Une commande est composée d’un code client codeclient, de la quantité


commandée quantité et du prix unitaire de l’article commandé prixunit.

Une facture est composée du code client codeclient et du montant de la facteur


montant.

On utilisera les définitions suivantes :

type
tcommande = article
codeclient, quantité : entier ;
prixunit : réel ;
fin ;
tfacture = article
codeclient : entier ;
montant : réel ;
fin ;
fcommande = fichier de tcommande;
ffacture = fichier de tfacture ;

1°/ On souhaite vérifier que le fichier de commandes est trié par ordre
croissant sur le code client. Écrire une fonction booléenne trié qui prend en
argument un fichier de commandes et retourne la valeur vrai si le fichier est trié
et faux sinon

2°/ Si un client a commandé n articles, on dispose de n bons de commande pour


ce client. On désire établir une facture pour chaque bon de commande. Le fichier
de commandes n’est pas trié. Écrire une procédure de facturation qui construit
un fichier de factures contenant toutes les factures établies pour chaque bon de
commande.

3°/ On suppose maintenant que le fichier de commandes est trié par ordre
croissant sur le code client et on souhaite connaître le nombre de clients
différents dans le fichier de commande. Écrire une fonction qui prend en
argument un fichier de commandes et retourne le nombre de clients différents
présents dans le fichier de commandes.

16
5 Dr Ndi Nyoungui André
Algorithmique et structures de données

4°/ Le fichier de commandes est toujours trié, et on veut établir une seule
facture pour tous les bons de commande d’un même client. Écrire une procédure
de facturation qui prend en argument un fichier de commandes et construit un
fichier de factures contenant une facture pour chaque client.

5°/ On dispose maintenant d’un fichier clients indiquant pour chaque client son
adresse. Ce fichier est trié sur codeclient. On utilisera les définitions
supplémentaires suivantes :

type
tclient = article
codeclient : entier ;
adresse : chaîne ;
fin ;
fclient = fichier de tclient ;

En supposant que le fichier clients est une variable globale de type fclient trié
sur codeclient, codeclient une variable globale de type entier, écrire un
algorithme qui prend en entrée un fichier de clients, un code client et retourne
l’adresse du client ayant cette adresse si celui est présent dans le fichier.
L’algorithme retourne aussi un booléen indiquant si la recherche a été fructueuse
ou non.

Remarque
Quand on invoque cet algorithme, on suppose que les premiers éléments de client
ont déjà été parcourus lors des appels précédents.
• clients est donc déjà ouvert en lecture,
• cet algorithme recherche l’adresse du client possédant le code codeclient,
• l’algorithme doit tenir compte du fait que le fichier clients est trié sur le
code client.

6°/ On dispose maintenant des structures de données suivantes :

type
tfacturebis = article
codeclient : entier ;
adresse : chaîne50 ;
montant : réel ;
fin ;
terreur = article
codeclient : entier ;
message : chaîne ;
fin ;
16
6 Dr Ndi Nyoungui André
Algorithmique et structures de données

fcommande = fichier de tcommande ;


ffacture = fichier de tfacture ;
ferreur = fichier de terreur ;
fclient = fichier de tclient ;
ffacturebis = fichier de tfacturebis ;

En supposant que le fichier commandes est une variable globale de type


fcommande trié sur codeclient, codeclient une variable globale de type entier,
écrire un algorithme qui recherche la première occurrence du prochain client
sachant que le fichier de commandes est déjà ouvert en lecture.

7°/ Écrire une procédure de facturation qui reçoit en entrée un fichier de


commandes, un fichier de clients trié sur codeclient et construit un fichier de
factures contenant les factures établies pour chaque client et un fichier
d’erreurs contenant les messages d’erreurs correspondant aux clients du fichier
de commandes non présents dans le fichier de clients.
Cette procédure a pour objet d’établir une seule facture pour toutes les
commandes d’un même client. L’algorithme doit tenir compte du fait que les deux
fichiers d’entrée sont triés.

8°/ On souhaite maintenant détecter les bons de commandes des clients afin de
leur faire un cadeau pour les fêtes de fin d’années. Pour cela on doit disposer du
montant de toutes les commandes de chaque client. On dispose de la structure
suivante :

type
tclient = article
codeclient : entier ;
adresse : chaîne ;
montant : réel ;
fin ;

Écrire une procédure de facturation qui reçoit en entrée un fichier de


commandes, un fichier de client trié sur codeclient et construit un fichier de
factures contenant les factures établies pour chaque client, un fichier de
facturebis et un fichier d’erreurs contenant les messages d’erreurs
correspondant aux clients du fichier de commandes non présents dans le fichier
de clients.

Solution

16
7 Dr Ndi Nyoungui André
Algorithmique et structures de données

1°/ On souhaite vérifier que le fichier de commandes est trié par ordre
croissant sur le code client. Écrire une fonction booléenne trié qui prend en
argument un fichier de commandes et retourne la valeur vrai si le fichier est trié
et faux sinon

On utilise l’algorithme fichiertrié du cours en l’adaptant aux variables


structurées.

fonction fichiertrié(nomfichier : chaîne) : booléen ;


variable
f : fcommande ;
courant, précédent : tcommande ;
codep, codecourant : entier ;
début
relire(f, nomfichier) ;
si fin(f) alors
fichiertrié ← vrai
sinon
début
lire(f, précédent) ;
si fin(f) alors
fichiertrié ← vrai
sinon
début
lire(f, courant) ;
codep ← précédent.codeclient ;
codecourant ← courant.codeclient ;
tanqtue non fin(f) et codep ≤ codecourant faire
début
codep ← codecourant ;
lire(f, courant) ;
codecourant ← courant.codeclient ;
fin ;
fichietrié ← codep ≤ codecourant ;
fin ;
fin ;
fermer(f) ;
fin ;

2°/ Si un client a commandé n articles, on dispose de n bons de commande pour


ce client. On désire établir une facture pour chaque bon de commande. Le fichier

16
8 Dr Ndi Nyoungui André
Algorithmique et structures de données

de commandes n’est pas trié. Écrire une procédure de facturation qui construit
un fichier de factures contenant toutes les factures établies pour chaque bon de
commande.

Il s’agit d’une simple création de fichier à partir d’un autre. On utilise


l’algorithme de copie du cours en l’adaptant au problème posé.

procédure facturation1(nomcom, nomfac : chaîne) ;


variable
f : fcommande ;
g : ffacture ;
commande : tcommande ;
facture : tfacture ;
début
relire(f, nomcom) ;
réécrire(g, nomfac) ;
tantque non fin(f) faire
début
lire(f, commande) ;
facture.codeclient ← commande.codeclient ;
facture.montant ← commande.quantité * commande.prixunit ;
écrire(g, facture) ;
fin ;
fermer(f) ;
fermer(g) ;
fin ;

3°/ On suppose maintenant que le fichier de commandes est trié par ordre
croissant sur le code client et on souhaite connaître le nombre de clients
différents dans le fichier de commande. Écrire une fonction qui prend en
argument un fichier de commandes et retourne le nombre de clients différents
présents dans le fichier de commandes.

C’est un parcours classique d’un fichier trié avec comptage d’éléments. Tous les
bons de commande d’un même client se suivent puisque le fichier est trié sur
code client. Deux clients consécutifs différents signifient que l’on passe d’un
client à un autre.

fonction nbclients(nomcom : chaîne) : entier ;


variable
commande : tcommande ;

16
9 Dr Ndi Nyoungui André
Algorithmique et structures de données

compte, codeprécédent : entier ;


f : fcommande ;
début
compte ← 0 ;
relire(f, nomcom) ;
si non fin(f) alors
début
lire(f, commande) ;
codeprécédent← commande.codeclient ;
compte ← 1 ;
tantque non fin(f) faire
début
lire(f, commande) ;
si codeprécédent ≠ commande.codeclient alors
compte ← compte + 1 ;
codeprécédent ← commande.codeclient ;
fin ;
fin ;
nbclients ← compte ;
fermer(f) ;
fin ;

4°/ Le fichier de commandes est toujours trié, et on veut établir une seule
facture pour tous les bons de commande d’un même client. Écrire une procédure
de facturation qui prend en argument un fichier de commandes et construit un
fichier de factures contenant une facture pour chaque client.

Le fichier de commandes est le fichier directeur. Il y a une seule itération. On


teste, au départ le cas du fichier vide.

procédure facturation2(nomcom, nomfac : chaîne) ;


variable
f : fcommande ;
g : ffacture ;
total : réel ;
code : entier ;
commande : tcommande ;
facture : tfacture ;
début
relire(f, nomcom) ;
réécrire(g, nomfac) ;

17
0 Dr Ndi Nyoungui André
Algorithmique et structures de données

si non fin(f) alors


début
lire(f, commande) ;
total ← commande.quantité * prixunit ;
codeclient← commande.codeclient ;
tantque non fin(f) faire
début
lire(f, com) ;
si codeclient ≠ commande.codeclient alors
début
facture.codeclient ← commande.codeclient ;
facture.montant ← total ;
écrire(g, facture) ;
lire(f, commande) ;
total ← commande.quantité * commande.priixunit ;
codeclient ← commande.coedclient ;
fin
sinon
total ← total + com.quantité * commande.prixunit ;
fin ;
facture.code← client codeclient ;
facture.montant ← total ;
écrire(g, facture) ;
fin ;
fermer(f) ;
fermer(g)
fin ;

5°/ On dispose maintenant d’un fichier clients indiquant pour chaque client son
adresse. Ce fichier est trié sur codeclient. On utilisera les définitions
supplémentaires suivantes :

type
tclient = article
codeclient : entier ;
adresse : chaîne ;
fin ;
fclient = fichier de tclient ;

En supposant que le fichier clients est une variable globale de type fclient trié
sur codeclient, codeclient une variable globale de type entier, écrire un
algorithme qui prend en entrée un fichier de clients, un code client et retourne

17
1 Dr Ndi Nyoungui André
Algorithmique et structures de données

l’adresse du client ayant cette adresse si celui est présent dans le fichier.
L’algorithme retourne aussi un booléen indiquant si la recherche a été fructueuse
ou non.

Cet algorithme est une procédure auxiliaire utilisée dans la procédure


facturation3. Son algorithme est le suivant :

procédure recherche(var adresse : chaîne ; var trouvé : booléen) ;


variable
client : tclient ;
début
si non fin(clients) alors
début
lire(clients, client) ;
tantque non fin(clients) et (client.codeclient < code) faire
lire(clients, client) ;
si client.codeclient = code alors
début
adresse ← client.adresse ;
trouvé ← vrai ;
fin
sinon
trouvé ← faux ;
fin ;
fermer(f) ;
fin ;

6°/ On dispose maintenant des structures de données suivantes :

type
tfacturebis = article
codeclient : entier ;
adresse : chaîne50 ;
montant : réel ;
fin ;
terreur = article
codeclient : entier ;
message : chaîne ;
fin ;
fcommande = fichier de tcommande ;
ffactures = fichier de tfacture ;

17
2 Dr Ndi Nyoungui André
Algorithmique et structures de données

ferreur = fichier de terreur ;


fclient = fichier de tclient ;
ffacturebis = fichier de tfacturebis ;

En supposant que le fichier commandes est une variable globale de type


fcommande trié sur codeclient, codeclient une variable globale de type entier,
écrire un algorithme qui recherche la première occurrence du prochain client
sachant que le fichier fcom est déjà ouvert en lecture.

Cet algorithme est aussi une procédure auxiliaire utilisée dans la procédure
facturation3.

procédure cliensuivant ;
début
lire(commandes, commande) ;
tantque non fin(commandes) et (commande.codeclient = codeclient) faire
lire(f, commande) ;
fin ;

7°/ Écrire une procédure de facturation qui reçoit en entrée un fichier de


commandes, un fichier de clients trié sur codeclient et construit un fichier de
factures contenant les factures établies pour chaque client et un fichier
d’erreurs contenant les messages d’erreurs correspondant aux clients du fichier
de commandes non présents dans le fichier de clients.
Cette procédure a pour objet d’établir une seule facture pour toutes les
commandes d’un même client. L’algorithme doit tenir compte du fait que les deux
fichiers d’entrée sont triés.

Au départ on confond le premier client et le client suivant, ce qui évite d’écrire


des actions spécifiques pour rechercher le premier client. Ensuite comme
facturation2, on itère sur le même client à l’intérieur de l’itération portant sur le
fichier fcom. On utilise une sentinelle H pour simplifier le traitement du dernier
élément.

procédure facturation3(nomcom, nomcli, nomfac, nomerr : chaîne) ;


variable
montantclient : réel ;
commande : tcommande ;
client : tclient ;
erreur : terreur ;
code : entier ;

17
3 Dr Ndi Nyoungui André
Algorithmique et structures de données

prochainclient : booléen ;
adresse : chaîné ;
fcoms : fcommande ;
clients : fclient ;
factures : ffacturebis ;
erreurs : ferreur ;
début
relire(fcoms, nomcom) ;
relire(clients, nomcli) ;
réécrire(factures, nomfac) ;
réécrire(erreurs, nomerr) ;
lire(fcom, commande) ;
tantque non fin(fcoms) faire
début
prochainclient ← faux ;
tantque non fin(fcoms) et (non prochainclient) faire
début
code ← commande.codeclient ;
recherche(adresse, prochainclient) ;
si non prochainclient alors
début
erreur.codeclient ← client.codeclient ;
erreur.message ← 'client inconnu' ;
écrire(erreurs, erreur) ;
clientsuivant ;
fin ;
fin ;
si prochainclient alors
début
montantclient ← commande.quantité * commande.prixunit ;
lire(fcom, commande) ;
tantque non fin(fcoms) et (code = commande.codeclient) faire
début
montantclient ← montantclient +
commande.quantité * commande.prixunit ;
lire(fcoms, commande) ;
fin ;
facture.codeclient ← codeclient ;
facture.montant ← montantclient ;
facture.adresse ← adresse ;
écrire(factures, facture) ;

17
4 Dr Ndi Nyoungui André
Algorithmique et structures de données

fin ;
fin ;
fermer(fcoms) ;
fermer(clients) ;
fermer(erreurs) ;
fin ;

8°/ On souhaite maintenant détecter les bons de commandes des clients afin de
leur faire un cadeau pour les fêtes de fin d’années. Pour cela on doit disposer du
montant de toutes les commandes de chaque client. On dispose de la structure
suivante :

type
tclient = article
codeclient : entier ;
adresse : chaîne ;
montant : réel ;
fin ;

Écrire une procédure de facturation qui reçoit en entrée un fichier de


commandes, un fichier de client trié sur codeclient et construit un fichier de
factures contenant les factures établies pour chaque client, un fichier de
facturebis et un fichier d’erreurs contenant les messages d’erreurs
correspondant aux clients du fichier de commandes non présents dans le fichier
de clients.

On utilise l’algorithme précédent en ajoutant le cumul des montants et la


construction du nouveau fichier ncli. Pour ce faire, il faut réécrire la procédure
auxiliaire clientsuivant afin de permettre la construction de ce nouveau fichier.

procédure facturation4(nomcom, nomcli, nomncli, nomfac, nomerr : chaîne) ;


variable
total : réel ;
com : tcommande ;
client : tclient ;
erreur : terreur;
codecli : entier ;
prochainclient : booléen ;
adresse : chaîné ;
fcoms : fcommande ;
clients, nclients : fclient ;

17
5 Dr Ndi Nyoungui André
Algorithmique et structures de données

factures : ffacturebis ;
erreurs : ferreur;
début
relire(fcoms, nomcom) ;
relire(clients, nomcli) ;
réécrire(factures, nomfac) ;
réécrire(erreurs, nomerr) ;
réécrire(nclients, nomncli) ;
lire(fcoms, com) ;
tantque non fin(fcoms) faire
début
{recherche client suivant}
prochainclient ← faux ;
tantque non fin(fcoms) et (non prochainclient) faire
début
codecli ← com.codeclient ;
recherche(adresse, prochainclient) ;
si non prochainclient alors
début
{codeclient n’est pas fcli, mise à jour de ferr}
erreur.codeclient ← client.codeclient ;
erreur.message ← 'client inconnu' ;
écrire(erreurs, erreur) ;
{cherche la première commande du prochain client}
clientsuivant ;
fin ;
fin ;
si prochainclient alors
début
total ← com.quantité * com.prixunit ;
lire(fcoms, com) ;
tantque non fin(fcoms) et (codecli = com.codeclient) faire
début
total ← total + com.quantité * com.prixunit ;
lire(fcoms, com) ;
fin ;
{mise à jour de ffac avec la facture du client précédent}
facture.codeclient ← codecli ;
facture.montant ← total ;
facture.adresse ← adresse ;
écrire(factures, facture) ;

17
6 Dr Ndi Nyoungui André
Algorithmique et structures de données

client.montant ← client.montant + total ;


fin ;
fin ;
{mise à jour de fcli et copie du reste}
écrire(nclients, client) ;
tantque non fin(clients) faire
début
lire(clients, client) ;
écrire(nclients, client) ;
fin ;
fermer(fcoms) ;
fermer(clients) ;
fermer(nclients) ;
fermer(erreurs) ;
fermer(factures) ;
fin ;

17
7 Dr Ndi Nyoungui André
Algorithmique et structures de données

Chapitre 8

Les listes linéaires chaînées

Exercice 8.1
Citez deux différences entres les structures de données statiques et les
structures de données dynamiques.

Réponse. (a) Le nombre de composantes dans une structure statique ne peut


être modifié pendant l’exécution du programme. Le nombre de composantes dans
une structure dynamique peut changer pendant l’exécution du programme
(b) Les inter-relations entre les composantes d’une variable statique ne peuvent
pas être modifiées. La structure d’une variable dynamique peut être modifiée
pendant l’exécution du programme.

Exercice 8.2
Définir des pointeurs pour pointer sur des variables de type entier, réel,
caractère, booléen, vecteur ou article.

Exercice 8.3
Que fait la procédure suivante ?
procédure parcoursliste(liste : pélément) ;
début
si liste ≠ nil faire
début
écrire(liste^.donnée) ;
parcoursliste(liste^.suivant) ;
écrire(liste^.donnée) ;
fin ;
fin ;

Prenons comme exemple la liste [liste] = (a, b, c)


La trace de la procédure parcoursliste(liste) est :

• parcoursliste((a, b, c))
•• écrire(a)
•• parcoursliste((b, c))
••• écrire(b)
17
8 Dr Ndi Nyoungui André
Algorithmique et structures de données

••• parcoursliste((c))
•••• écrire(c)
•••• parcoursliste(nil)
•••• écrire(c)
••• écrire(b)
•• écrire(a)

On obtient donc comme la sortie la chaîne : abccba

Donc, si on appelle [miroir] la liste (c, b, a) et [liste] la liste (a, b, c),


parcoursliste(liste) fait écrire [liste] || [miroir]. D’une manière générale, la
procédure parcoursliste(liste) fait écrire les éléments de la liste suivis par les
éléments de la liste dans l’ordre inverse.

Exercice 8.4
Que fait la procédure suivante ?
procédure parcoursliste(liste : pélément) ;
début
si liste ≠ nil faire
début
parcoursliste(liste^.suivant) ;
écrire(liste^.donnée) ;
parcoursliste(liste^.suivant) ;
fin ;
fin ;

Prenons encore comme exemple la liste [liste] = (a, b, c)


La trace de la procédure parcoursliste(liste) est :

• parcoursliste((a, b, c))
•• parcoursliste((b, c))
••• parcoursliste((c))
•••• parcoursliste(nil)
•••• écrire(c)
•••• parcoursliste(nil)
••• écrire(b)
••• parcoursliste(c)
•••• parcoursliste(nil)
•••• écrire(c)
•••• parcoursliste(nil)
•• écrire(a)
•• parcoursliste((b, c))

17
9 Dr Ndi Nyoungui André
Algorithmique et structures de données

••• parcoursliste((c))
•••• parcoursliste(nil)
•••• écrire(c)
•••• parcoursliste(nil)
••• écrire(b)
••• parcoursliste(c)
•••• parcoursliste(nil)
•••• écrire(c)
•••• parcoursliste(nil)

On obtient donc comme sortie la chaîne : cbcacbc

Exercice 8.5
Écrire un algorithme qui retourne la valeur de la dernière cellule d’une liste
linéaire chaînée.

L’algorithme est le suivant :


procédure dernierval(liste : pélément ; var elem : télément ; var trouvé :
booléen) ;
variable
courant : pélément ;
début
trouvé ← faux ;
si liste ≠ nil alors
début
courant ← liste ;
trouvé ← vrai ;
tantque courant^.suivant ≠ nil faire
courant ← courant^.suivant
elem ← courant^.donnée ;
fin ;
fin ;

Exercice 8.6
Écrire un algorithme qui détermine le plus grand élément dans une liste linéaire
chaînée.

L’algorithme est le suivant :


procédure grandliste(liste : pélément ; var grand : télément ; var trouvé :
booléen) ;
variable
courant : pélément ;

18
0 Dr Ndi Nyoungui André
Algorithmique et structures de données

début
si liste = nil alors
trouvé ← faux
sinon
début
courant ← liste ;
grand ← liste^.donnée ;
trouvé ← vrai ;
tantque courant ≠ nil faire
début
si grand < courant^.donnée alors
grand ← courant^.donnée ;
courant ← courant^.suivant ;
fin ;
fin ;
fin ;

Exercice 8.7
Écrire un algorithme qui détermine le plus petit élément dans une liste linéaire
chaînée.

L’algorithme est le suivant :


procédure petitliste(liste : pélément ; var petit : télément ; var trouvé :
booléen) ;
variable
courant : pélément ;
début
si liste = nil alors
trouvé ← faux
sinon
début
courant ← liste ;
petit ← liste^.donnée ;
trouvé ← vrai ;
tantque courant ≠ nil faire
début
si petit > courant^.donnée alors
petit ← courant^.donnée ;
courant ← courant^.suivant ;
fin ;
fin ;

18
1 Dr Ndi Nyoungui André
Algorithmique et structures de données

fin ;

Exercice 8.8
Écrire une fonction qui prend en entrée une liste chaînée et retourne la position
du plus grand élément de la liste. On suppose que le plus grand élément est
unique et que la fonction retourne zéro si la liste est vide.

L’algorithme est le suivant :


fonction positiongrand(liste : pélément) : entier ;
variable
courant : pélément ;
indice, compteur : entier ;
grand : télément ;
début
si liste = nil alors
positiongrand ← 0
sinon
début
grand ← liste^.donnée ;
compteur ← 1 ;
indice ← 1 ;
courant ← liste^.suivant ;
tantque courant ≠ nil faire
début
compteur ← compteur + 1 ;
si grand < courant^.donnée alors
début
grand ← courant^.donnée ;
indice ← compteur ;
fin ;
courant ← courant^.suivant ;
fin ;
positiongrand ← indice ;
fin ;
fin ;

Exercice 8.9
Écrire une fonction qui prend en entrée une liste chaînée et retourne la position
du plus petit élément de la liste. On suppose que le plus grand élément est unique
et que la fonction retourne zéro si la liste est vide.

L’algorithme est le suivant :

18
2 Dr Ndi Nyoungui André
Algorithmique et structures de données

fonction positionpetit(liste : pélément) : entier ;


variable
courant : pélément ;
indice, compteur : entier ;
petit : télément ;
début
si liste = nil alors
positionpetit ← 0
sinon
début
petit ← liste^.donnée ;
compteur ← 1 ;
indice ← 1 ;
courant ← liste^.suivant ;
tantque courant ≠ nil faire
début
compteur ← compteur + 1 ;
si petit > courant^.donnée alors
début
petit ← courant^.donnée ;
indice ← compteur ;
fin ;
courant ← courant^.suivant ;
fin ;
positionpetit ← indice ;
fin ;
fin ;

Exercice 8.10
Écrire une procédure qui prend en entrée une liste chaînée et retourne le plus
grand et le second plus grand éléments de la liste.

On peut s’inspirer de l’algorithme que nous avons développé dans le cas des
vecteurs pour résoudre ce problème.

L’algorithme est alors le suivant :


procédure grandsecond(liste : pélément ; var grand, second : télément ;
var trouvé : booléen) ;
variable
p : pélément ;
indice, compteur : entier ;
petit : pélément ;

18
3 Dr Ndi Nyoungui André
Algorithmique et structures de données

début
si liste = nil alors
trouvé ← faux
sinon
début
trouvé ← vrai ;
si liste^.suivant = nil alors
début
grand ← liste^.donnée ;
second ← liste^.donnée ;
fin
sinon
début
{trouver le plus grand}
grand ← liste^.donnée ;
p ← liste^.suivant ;
tantque p ≠ nil faire
début
si grand < p^.donnée alors
grand ← p^.donnée ;
p ← p^.suivant ;
fin ;
{trouver le second plus grand}
si liste^.donnée ≠ grand alors
second ← liste^.donnée
sinon
second ← liste^.suivant^.donnée ;
p ← liste^.suivant ;
tantque p ≠ nil faire
début
si grand ≠ p^.donnée alors
si second < p^.donnée alors
second ← p^.donnée ;
p ← p^.suivant ;
fin ;
fin ;
fin ;
fin ;

Exercice 8.11
Écrire une fonction qui prend en entrée une liste chaînée de nombres réels
retourne la somme des éléments de la liste.

18
4 Dr Ndi Nyoungui André
Algorithmique et structures de données

L’algorithme est le suivant :


fonction sommeliste(liste : pélément) : réel ;
variable
courant : pélément ;
somme : réel ;
début
si liste = nil alors
somme ← 0
sinon
début
somme ← 0 ;
courant ← liste ;
tantque courant ≠ nil faire
début
somme ← somme + courant^.donnée ;
courant ← courant^.suivant ;
fin ;
sommeliste ← somme ;
fin ;
fin ;

Exercice 8.12
On désire connaître l’adresse de la dernière occurrence d’une valeur dans une
liste. Écrire sous forme itérative et sous forme récursive la fonction qui délivre
cette adresse ou nil si la valeur n’est pas présente dans la liste.

Schéma itératif, première version

L’algorithme est le suivant :


fonction pointeurdernier(liste : pélément ; val : télément) : pélément ;
variable
courant, dernier : pélément ;
début
dernier ← nil ;
courant ← liste ;
tantque courant ≠ nil faire
début
si courant^.donnée = val alors
dernier ← courant ;
courant ← courant^.suivant ;
fin ;

18
5 Dr Ndi Nyoungui André
Algorithmique et structures de données

pointeurdernier ← dernier ;
fin ;

Schéma itératif, deuxième version

On peut aussi utiliser la fonction pointeurval. Dans ce cas, la version itérative


serait la suivante :

L’algorithme est le suivant :


fonction pointeurdernier(liste : pélément ; val : télément) : pélément ;
variable
courant, dernier : pélément ;
début
dernier ← nil ;
courant ← pointeurval(liste, val) ;
tantque courant ≠ nil faire
début
dernier ← courant ;
courant ← pointeurval(courant, val) ;
fin ;
pointeurdernier ← dernier ;
fin ;

Schéma récursif, première version

Pour la version récursive, on doit conserver à chaque appel l’adresse de la


dernière occurrence trouvée. On passe donc la valeur de cette adresse en
paramètre. Cette valeur devra être initialisée à nil avant l’appel.
Le raisonnement est le suivant : si la liste est vide, on retourne dernier. Si elle
n’est pas vide, on regarde si liste^.donnée est égal à val. Si oui dernier on met
dans dernier la valeur de liste et on continue la recherche dans liste^.suivant
sinon on continue seulement la recherche dans liste^.suivant.

L’algorithme est alors le suivant :


fonction pointeurdernier(liste : pélément ; val : télément ;
var der : pélément) : pélément ;
début
si liste = nil alors
pointeurdernier ← der
sinon
si liste^.donnée =val alors
début
der ← liste ;
18
6 Dr Ndi Nyoungui André
Algorithmique et structures de données

pointeurdernier ← pointeurdernier(liste^.suivant, val,


der)
fin
sinon
pointeurdernier ← pointeurdernier(liste^.suivant, val, der)
fin ;

Schéma récursif, deuxième version

On peut aussi donner une version récursive proche du parcours droite gauche
donné en cours. Il s’agit alors de trouver la première de la valeur val en
commençant par la fin de liste.

L’algorithme est alors le suivant :


procédure pointeurdernier(liste : pélément ; val : télément ; var der : pélément) ;
début
si liste = nil alors
der ← nil
sinon
début
pointeurdernier(liste^.suivant, val, der) ;
si (liste^.donnée = val) et (der = nil) alors
der ← liste ;
fin ;
fin ;

Exercice 8.13
Écrire, sous forme récursive et sous forme itérative, un algorithme qui vérifie
qu’une liste est triée par ordre décroissant.

Schéma récursif

L’algorithme est le suivant :


fonction décroissant(liste : pélément) : booléen ;
début
si liste = nil alors
décroissant ← vrai
sinon
si liste^.suivant = nil alors
décroissant ← vrai
sinon
si liste^.donnée ≥ liste^.suivant^.donnée alors
décroissant ← décroissant(liste^.suivant)
18
7 Dr Ndi Nyoungui André
Algorithmique et structures de données

sinon
décroissant ← faux ;
fin ;

Schéma itératif

L’algorithme est le suivant :


fonction décroissant(liste : pélément) : booléen ;
variable
p : pélément ;
début
si liste = nil alors
décroissant ← vrai
sinon
début
p ← liste ;
tantque (p^.suivant ≠ nil) et alors (p^.donnée ≥ p^.suivant^.donnée)
alors
p ← p^.suivant ;
décroissant ← p^.suivant = nil ;
fin ;
fin ;

Exercice 8.14
Écrire, sous forme itérative, un algorithme de recherche de la première
occurrence d’une valeur val dans une liste triée.

L’algorithme est le suivant :


fonction pointeurval(liste : pélément ; val : télément) : pélément ;
variable
courant : pélément ;
début
courant ← liste ;
tantque (courant ≠ nil) et alors (courant^.donnée < val) faire
courant ← courant^.suivant ;

si (courant = nil) ou sinon (courant^.donnée = val) alors


pointeurval ← courant
sinon
pointeurval ← nil ;
fin ;

18
8 Dr Ndi Nyoungui André
Algorithmique et structures de données

Exercice 8.15
Écrire, sous forme itérative et sous forme récursive, un algorithme de
recherche de la dernière occurrence d’une valeur dans une liste triée.

Schéma itératif

L’algorithme est le suivant :


procédure pointeurdernier(liste : pélément ; val : télément ; var der : pélément) ;
variable
courant : pélément ;
début
courant ← liste ;
der ← nil ;
tantque (courant ≠ nil) et alors (courant^.donnée ≤ val) faire
début
si courant^.donnée = val alors
der ← courant ;
courant ← courant^.suivant ;

fin ;
fin ;

Schéma récursif

L’algorithme est le suivant :


procédure pointeurdernier(liste : pélément ; val : télément ; var der : pélément) ;
début
si liste <> nil alors
si liste^.donnée < val alors
pointeurdernier(liste^.suivant, val, der)
sinon
si liste^.donnée = val alors
début
der ← liste ;
pointeurdernier(liste^.suivant, val, der) ;
fin ;
fin ;

Exercice 8.16
Écrire, sous forme itérative et sous forme récursive, l’algorithme d’insertion d’un
élément avant la première occurrence d’une valeur.

Schéma récursif
18
9 Dr Ndi Nyoungui André
Algorithmique et structures de données

L’algorithme est le suivant :


procédure insertavant(var liste : pélément, val, elem : télément ;
var possible :
booléen) ;
début
si liste = nil alors
possible ← faux
sinon
si liste^.donnée = val alors
début
possible ← vrai ;
insertête(liste, val, elem)
fin
sinon
inseravant(liste^.suivant, val, elem)
fin ;

Schéma itératif

L’algorithme est le suivant :


procédure insertavant(var liste : pélément ; val, elem : télément ;
var possible :
booléen) ;
variable
p : pélément ;
début
si liste = nil alors
possible ← faux
sinon
si liste^.donnée = val alors
début
possible ← vrai ;
insertête(liste, elem) ;
fin
sinon
début
p ← liste ;
tantque (p^.suivant ≠ nil)
et alors (p^.suivant^.donnée ≠ val)
faire

19
0 Dr Ndi Nyoungui André
Algorithmique et structures de données

p ← p^.suivant ;

si p^.suivant ≠ nil alors


insertête(p^.suivant, elem) ;
fin ;
fin ;

Exercice 8.17
Écrire, sous forme itérative et sous forme récursive, l’algorithme d’insertion d’un
élément après chaque occurrence d’une valeur.

Version récursive

Le raisonnement est le suivant : lorsqu’on entre dans la procédure, on regarde si


la valeur de valeur liste est différente de nil (première condition pour une
insertion probable). Si elle en effet différente de nil, on regarde si la donnée qui
est stockée en tête de liste est égale à val. Si cela est le cas, on procède à une
insertion en tête de liste^.suivant et on appelle de nouveau la procédure, mais
cette fois avec liste^.suivant^.suivant au lieu de liste^.suivant comme premier
paramètre pour éviter de boucle indéfiniment. Si la donnée qui est stockée en
tête de liste est différente de val, on appelle de nouveau la procédure, mais
cette fois avec liste^.suivant comme premier paramètre.

L’algorithme est alors le suivant :


procédure insertaprèstoutes(liste : pélément ; val, elem : télément) ;
début
si liste ≠ nil alors
si liste^.donnée = val alors
début
insertête(liste^.suivant, elem) ;
insertaprèstoutes(liste^.suivant^.suivant, val, elem) ;
fin
sinon
insertaprèstoutes(liste^.suivant, val, elem) ;
fin ;

Schéma itératif

L’algorithme est alors le suivant :


procédure insertaprèstoutes(var liste : pélément ; val, elem : télément) ;
variable
courant : pélément ;
début

19
1 Dr Ndi Nyoungui André
Algorithmique et structures de données

si liste ≠ nil alors


début
courant ← liste ;
tantque courant ≠ nil faire
si courant^.donnée = val alors
début
insertête(courant^.suivant, elem) ;
courant^ ← courant^.suivant^.suivant ;
fin
sinon
courant ← courant^.suivant ;
fin ;
fin ;

Exercice 8.18
Écrire, sous forme itérative et sous forme récursive, l’algorithme d’insertion d’un
élément avant chaque occurrence d’une valeur.

Schéma récursif

Le raisonnement est le suivant : lorsqu’on entre dans la procédure, on regarde si


la valeur de valeur liste est différente de nil (première condition pour une
insertion probable). Si elle en effet différente de nil, on regarde si la donnée qui
est stockée en tête de liste est égale à val. Si cela est le cas, on procède à une
insertion en tête de liste et on appelle de nouveau la procédure, mais cette fois
avec liste^.suivant^.suivant au lieu de liste^.suivant comme premier paramètre
pour éviter de boucle indéfiniment. Si la donnée qui est stockée en tête de liste
est différente de val, on appelle de nouveau la procédure, mais cette fois avec
liste^.suivant comme premier paramètre.

L’algorithme est alors le suivant :


procédure insertavanttoutes(var liste : pélément, val, elem : télément) ;
début
si liste ≠ nil alors
si liste^.donnée = val alors
début
insertête(liste, val, elem) ;
insertavanttoutes(liste^.suivant^.suivant, val, elem) ;
fin
sinon
inseravanttoutes(liste^.suivant, val, elem)
fin ;

19
2 Dr Ndi Nyoungui André
Algorithmique et structures de données

Schéma itératif

Il faut prévoir l’insertion en tête de liste et ensuite ne pas oublier de protéger


le paramètre liste lors du parcours. L’algorithme se décompose alors en deux
parties :
• insertion en tête de liste qui correspond à l’initialisation,
• insertion non en tête de liste qui correspond au cas général.

Pour pouvoir une insertion avant une occurrence de la valeur val, on a besoin de
connaître l’adresse de la cellule qui précède celle qui contient la valeur val. On va
donc utiliser la variable p^.suivant qui permet de sonder la valeur d’une cellule en
restant positionner sur celle qui la précède. Chaque fois qu’une insertion est
effectuée, on exécute l’instruction d’affectation p^ ← p^.suivant^.suivant pour
éviter de tourner en rond indéfiniment.

L’algorithme est alors le suivant :


procédure insertavant(var liste : pélément ; val, elem : télément) ;
variable
p : pélément ;
début
si liste ≠ nil alors
début
si liste^.donnée = val alors
insertête(liste, elem) ;
sinon
début
p ← liste ;
tantque p^.suivant ≠ nil faire
si p^.suivant^.donnée = val alors
début
insertête(p^.suivant, elem) ;
p^ ← p^.suivant^.suivant ;
fin
sinon
p ← p^.suivant ;
fin ;
fin ;
fin ;

Exercice 8.19
Réécrire la procédure ci-dessus dans le cas d’une liste avec une sentinelle en
tête de liste.

19
3 Dr Ndi Nyoungui André
Algorithmique et structures de données

L’utilisation de la sentinelle permet de simplifier l’initialisation : le cas particulier


de l’insertion en tête de liste n’existe plus. Le paramètre liste est alors passé par
valeur.

L’algorithme est alors le suivant :


procédure insertavant(liste : pélément ; val, elem : télément) ;
variable
p : pélément ;
début
p ← liste ;
tantque p^.suivant ≠ nil faire
si p^.suivant^.donnée = val alors
début
insertête(p^.suivant, elem) ;
p^ ← p^.suivant^.suivant ;
fin
sinon
p ← p^.suivant ;
fin ;

Exercice 8.20
On suppose que l’on les définitions de type suivantes :
type
pétudiant = ^tétudiant ;
pétudiant = article
nom : chaîne ;
prénom : chaîne ;
suivant : pétudiant ;
fin ;

Écrire une procédure qui prend en entrée un fichier d’étudiants et les insère
dans une liste chaînée par ordre alphabétique. Si deux étudiants ont le même
nom, on les classe par rapport à leurs prénoms.

L’algorithme d’insertion d’un élément dans une liste triée d’étudiants est le
suivant :

procédure insertion(var liste : pétudiant ; elem : tétudiant) ;


début
si (liste = nil) alors
insertête(liste, elem)
sinon

19
4 Dr Ndi Nyoungui André
Algorithmique et structures de données

si (liste^.nom > elem.nom) alors


insertête(liste, elem)
sinon
si (liste^.nom = elem.nom) et (liste^.prénom ≥ elem.prénom)
alors
insertête(liste, elem)
sinon
insertion(liste^.suivant, elem) ;
fin ;

L’algorithme est le suivant :


procédure créerliste(nomfichier : chaîne ; var liste : pétudiant) ;
variable
f : fichier de tétudiant ;
elem : tédutiant ;
début
relire(f, nomfichier) ;
liste ← nil ;
tantque non fin(f) faire
début
lire(f, elem) ;
insertion(liste, elem) ;
fin ;
fermer(f) ;
fin ;

Exercice 8.21
Écrire sous forme récursive et sous forme itérative l’algorithme de suppression
de toutes les occurrences d’une valeur dans une liste

Schéma récursif, première version

On utilise un parcours gauche droite. Le raisonnement est le suivant :

L’algorithme est alors le suivant :


procédure supprimetoutes(var liste : pélément ; elem : télément) ;
début
si liste ≠ nil alors
si liste^.donnée = elem alors
début
supptête(liste) ;
supprime(liste, elem) ;

19
5 Dr Ndi Nyoungui André
Algorithmique et structures de données

fin
sinon
supprimetoutes(liste^.suivant, elem) ;
fin ;

Schéma récursif, deuxième version

On utilise un parcours droite gauche. Le raisonnement est le suivant :

L’algorithme est alors le suivant :


procédure supprimetoutes(var liste : pélément ; elem : télément) ;
début
si liste ≠ nil alors
si liste^.donnée = elem alors
début
supprimetoutes(liste^.suivant, elem) ;
supptête(liste) ;
fin ;
fin ;

Schéma itératif

L’algorithme est le suivant :


procédure supprimetoutes(var liste : pélément ; elem : télément) ;
variable
précédent, courant : pélément ;
début
tantque (liste ≠ nil) et alors (liste^.donnée = elem) faire
début
précédent ← liste ;
courant ← précédent^.suivant ;
tantque courant ≠ nil faire
début
si liste^.donnée = elem alors
supptête(précédent^.suivant) ;
sinon
précédent ← courant ;
courant ← précédent^.suivant ;
fin ;
fin ;
fin ;

Exercice 8.22

19
6 Dr Ndi Nyoungui André
Algorithmique et structures de données

Écrire sous forme récursive et sous forme itérative l’algorithme de suppression


de la première occurrence d’une valeur dans une liste triée.

Schéma récursif

L’algorithme est le suivant :


procédure supprimepr(var liste : pélément ; elem : télément) ;
début
si liste ≠ nil alors
si liste^.donnée = elem alors
supptête(liste)
sinon
si liste^.donnée < elem alors
supprimepr(liste^.suivant, elem) ;
fin ;

Schéma itératif

On suppose que la liste a une sentinelle en tête. Le raisonnement est le suivant :…

L’algorithme est alors le suivant :


procédure supprimepr(var liste : pélément ; elem : télément) ;
variable
p : pélément ;
début
p ← liste ;
tantque (p^.suivant ≠ nil) et alors (p^.suivant^.donnée < elem) faire
p ← p^.suivant ;

si (p^.suivant ≠ nil) et alors (p^.suivant^.donnée = elem) alors


supptête(p^.suivant) ;
fin ;

Exercice 8.23
Écrire sous forme récursive et sous forme itérative l’algorithme de suppression
de toutes les occurrences d’une valeur dans une liste triée.

Schéma récursif

L’algorithme est le suivant :


procédure supptoutes(var liste : pélément ; elem : télément) ;
début
si liste ≠ nil alors
si liste^.donnée = elem alors

19
7 Dr Ndi Nyoungui André
Algorithmique et structures de données

début
supptête(liste) ;
supptoutes(liste, elem) ;
fin
sinon
supptoutes(liste^.suivant, elem) ;
fin ;

Schéma itératif

On suppose que la liste a une sentinelle en tête.

L’algorithme est alors le suivant :


procédure supptoutes(var liste : pélément ; elem : télément) ;
variable
p : pélément ;
début
p ← liste ;
tantque (p^.suivant ≠ nil) et alors (p^.suivant^.donnée ≤ elem) faire
si p^.suivant^.donnée = elem alors
supptête(p^.suivant)
sinon
p ← p^.suivant ;
fin ;

Exercice 8.24
Que fait la procédure suivante ?

procédure Mystère(p : pélément) ;


variable
q : pélément ;
début
q ← p^.suivant ;
si q ≠ nil alors
début
p^ ← q^ ;
p^.suivant ← q^.suivant ;
libérer(q) ;
fin
fin ;

Pourquoi l’instruction si est-elle nécessaire dans cette procédure ?

19
8 Dr Ndi Nyoungui André
Algorithmique et structures de données

Réponse. La procédure supprime la cellule qui est pointée par p en copiant


d’abord le contenant de la cellule suivante dans p^ et en supprimant la cellule
suivante.

L’instruction si est nécessaire parce que la procédure ne marchera pas si p pointe


sur la dernière cellule de la liste.

Exercice 8.25
Les listes circulaires ou anneaux. Les listes circulaires ou anneaux sont des
listes linéaires dans lesquelles le dernier élément pointe sur le premier. Il n’y a
donc ni premier ni dernier, mais il est nécessaire de garder un seul point d’entrée
dans l’anneau, que nous appellerons liste, pour faciliter l’écriture des algorithmes
sur les anneaux.

Ces listes sont très utilisées en programmation système et dans les systèmes de
gestion de bases de données. Une liste circulaire permet de chaîner entre eux
des éléments possédant une même propriété. Il suffit alors de connaître un
élément possédant cette propriété pour obtenir, par parcours de la liste
circulaire, tous les autres.

1. Écrire un algorithme pour créer une liste circulaire à partir des éléments
d’un fichier.
2. Écrire un algorithme de parcours d’une liste circulaire.
3. Écrire un algorithme qui délivre l’adresse de la cellule de valeur val dans un
anneau ou nil si val n’est présente dans l’anneau.
4. Écrire un algorithme d’insertion d’un nouvel élément avant une valeur val
dans une liste circulaire.
5. Écrire un algorithme d’insertion d’un nouvel élément après une valeur val
dans une liste circulaire.
6. Écrire un algorithme de suppression de la cellule de valeur val dans une
liste circulaire.

Création d’un anneau

On se propose de créer une liste linéaire chaînée de la forme :

liste

19
9 Dr Ndi Nyoungui André
Algorithmique et structures de données

Nous utilisons la deuxième version de l’algorithme de création d’une liste chaînée


à partir des éléments d’un fichier que nous avons donnée en cours, mais en reliant
de la dernière à la première à la sortie.

L’algorithme est alors le suivant :


procedure créeranneau(nomfichier : chaîner ; var liste : pélément) ;
variable
dernier, courant : pélément ;
élément : télément ;
f : fichier de télément ;
début
relire(f , nomfichier) ;
si fin(f) alors
liste ← nil
sinon
début
nouveau(liste) ;
lire(f, élément) ;
liste^.donnée ← élément ;
dernier ← liste ;
tantque non fin(f) faire
début
lire(f, élément) ;
nouveau(courant) ;
dernier^.suivant ← courant;
dernier ← courant ;
courant^.donnée ← élément ;
fin ;
{Relier la dernière cellule à la première}
dernier^.suivant ← liste ;
fin ;
fermer(f) ;
fin;

Parcours d’une liste circulaire

L’algorithme est semblable à celui du parcours d’une liste classique. Toutefois,


pour éviter de boucler indéfiniment, on utilise un indicateur booléen qui
permettra de savoir qu’on a déjà effectué un tour complet de l’anneau.

L’algorithme est alors le suivant :


procédure parcours(liste : pélément) ;

20
0 Dr Ndi Nyoungui André
Algorithmique et structures de données

variable
p : pélément ;
stop : booléen ;
début
p ← liste ;
stop ← p = nil ;
tantque non stop faire
début
traiter(p) ;
p ← p^.suivant ;
stop ← p = liste ;
fin ;
fin ;

Recherche associative dans une liste circulaire

L’algorithme est assez simple : il suffit de parcourir l’anneau à la recherche de la


première cellule qui contient la valeur val. La fonction retourne la valeur nil si la
valeur val ne se trouve pas dans l’anneau.

L’algorithme est alors le suivant :


procédure rechercheval(liste : pélément ; val : télément) : pélément ;
variable
p : pélément ;
fini : booléen ;
trouvé : booléen ;
début
p ← liste ;
fini ← liste = nil ;
trouvé ← faux ;
rechercheval ← nil ;
tantque (non fini) et (non trouvé) faire
début
si p^.donnée = val alors
début
rechercheval ← p ;
trouvé ← vrai ;
fin ;
p ← p^.suivant ;
fini ← p = liste ;
fin ;
fin ;

20
1 Dr Ndi Nyoungui André
Algorithmique et structures de données

Insertion avant une valeur dans un anneau

Avant d’aborder le cas général, nous commençons par le cas particulier de


l’insertion en tête de liste (entrée de l’anneau).

1°/ Insertion d’un élément en tête de liste

C’est un algorithme très important que nous utiliserons pour réaliser les autres
insertions. On notera en outre que c’est un cas très particulier car l’insertion en
tête modifie non seulement l’adresse du point d’entrée mais aussi celle de la
cellule précédente pour préserver la boucle. On peut schématiser cet algorithme
comme suit :

liste
(b)

(a)

(c)

Il suffit de réaliser les liaisons (a), (b) et (c) dans cet ordre.

L’algorithme est alors le suivant :


procédure insertête(var liste : pélément; elem : télément) ;
variable
p, q : pélément ;
début
p ← liste ;
tantque p^.suivant ≠ liste faire
p ← p^.suivant ;
nouveau(q) ;
q^.donnée ← elem ;
q^.suivant ← liste ;
liste ← q ;
p^.suivant ← liste ;
fin ;

Insertion avant une valeur dans le cas général

L’algorithme est assez simple : il suffit de connaître l’adresse de la cellule qui


précède la première occurrence de la valeur val pour pouvoir réaliser, d’après le
schéma ci-dessous, les liaisons (a) et (b) dans cet ordre.

20
2 Dr Ndi Nyoungui André
Algorithmique et structures de données

liste

val

(b) (a)

élément à insérer

L’algorithme est alors le suivant :


procédure insertavant(var liste : pélément ; val, elem : télément) ;
variable
p, q : pélément ;
début
si liste ≠ nil alors
si liste^.donnée = val alors
insertête(liste, elem)
sinon
début
p ← liste ;
tantque (p^.suivant ≠ liste) et (p^.suivant^.donnée ≠ val) faire
p ← p^.suivant ;
si p^.suivant ≠ liste alors
début
nouveau(q) ;
q^.donnée ← elem ;
q^.suivant ← p^.suivant ;
p^.suivant ← q ;
fin ;
fin ;
fin ;

Insertion après une valeur

L’algorithme est assez simple : il suffit de connaître l’adresse e la cellule qui


contient liste
la première occurrence de la valeur val pour pouvoir réaliser, d’après le
schéma ci-dessous, les liaisons (a) et (b) dans cet ordre.

val

(b) (a)
20
3 Dr Ndi Nyoungui André
p

élément à insérer
Algorithmique et structures de données

L’algorithme est alors le suivant :


procédure insertaprès(var liste : pélément ; val, elem : télément;
var possible : booléen) ;
variable
p, pval : pélément ;
début
pval ← rechercheval(liste, val) ;
si pval = nil alors
possible ← faux
sinon
début
possible ← vrai ;
nouveau(p) ;
p^.donnée ← elem ;
p^.suivant ← pval^.suivant ;
pval^.suivant ← p ;
fin ;
fin ;

Suppression associative dans un anneau

Comme pour les insertions, on a le cas de la suppression de la première cellule qui


a pour conséquence de modifier l’adresse de la liste et celle de la cellule qui la
précède pour préserver la boucle. Dans le cas général, il suffit, comme le montre
le schéma, de modifier le contenu d’un pointeur.

(a)
liste

L’élément à supprimer sera déterminé par sa valeur (suppression associative).


20
4 Dr Ndi Nyoungui André
Algorithmique et structures de données

Suppression de la tête de liste

On suppose que la liste n’est pas vide. Le schéma est le suivant :

(a) (b)
liste

On suppose également que l’on a plus besoin de la cellule supprimée et que l’on la
rend au réservoir de cellules. Il faut donc préserver l’adresse de la tête de liste
avant d’effectuer la modification de cette adresse.
Il suffit d’effectuer les liaisons (a) et (b) dans cet ordre. Pour effectuer la
liaison (b), on doit connaître l’adresse de la cellule qui précède la tête de liste
dans l’anneau.

L’algorithme est alors le suivant :


procédure supptête(var liste : pélément) ;
variable
p, q : pélément ;
début
p ← liste ;
tantque p^.suivant ≠ liste faire
p ← p^.suivant ;
q ← liste ;
liste ← liste^.suivant ;
p^.suivant ← liste ;
libérer(q) ;
fin ;

Après traiter le cas de la suppression de la première cellule, on utilise le


raisonnement suivant dans le cas général : Pour supprimer la cellule qui contient
la valeur val, il faut connaître l’adresse de la cellule précédente.

L’algorithme est alors le suivant :


procédure supprime(var liste : pélément ; val : télémént; var possible : booléen) ;
variable
p, q : pélément ;
début
possible ← faux ;
20
5 Dr Ndi Nyoungui André
Algorithmique et structures de données

si liste ≠ nil alors


si liste^.donnée = val alors
début
possible ← vrai ;
supptête(liste) ;
fin
sinon
début
p ← liste ;
tantque (p^.suivant ≠ liste) et (p^.suivant^.donnée ≠
val) faire
p ← p^.suivant ;
si p^.suivant^.donnée = val faire
début
possible ← vrai ;
q ← p^.suivant ;
p^.suivant ← p^.suivant^.suivant ;
libérer(q) ;
fin ;
fin ;
fin ;

Exercice 8.26
Une liste doublement chaînée est une liste dans laquelle chaque cellule a un
pointeur sur la cellule précédente et un pointeur sur la cellule suivante.
1. Écrire un algorithme d’insertion d’un élément avant une valeur val.
2. Écrire un algorithme d’insertion d’un élément après une valeur val
3. Écrire un algorithme d’insertion d’un élément à la kème place.
4. Écrire un algorithme d’insertion de la valeur elem après chaque occurrence
de la valeur val.
5. Écrire un algorithme de suppression d’une valeur val.
6. Écrire un algorithme de suppression de la kème cellule.
7. Écrire un algorithme de suppression de toutes les occurrences de la valeur
val.

On utilise des cellules définies par le type pointeur :

type
pélément = ^tcellule;
tcellule = article
précédent : pélément ;
donnée : télément;

20
6 Dr Ndi Nyoungui André
Algorithmique et structures de données

suivant : pélément ;
fin ;

Insertion avant une valeur

Il s’agit d’insérer un élément elem avant la première occurrence de la valeur val.


Comme précédemment on utilise un paramètre possible qui permettra de savoir si
cette insertion a pu être réalisée ou non. Supposons que la variable pval
contienne l’adresse de la cellule qui contient la première occurrence de la valeur
val et la variable p l’adresse de la cellule à insérer.

Dans le cas général, on a la situation suivante :


liste pval

val

(d) (b) (c) (a)

elm
p

Il faut effectuer les modifications des pointeurs (a), (b), (c), (d) et faire surtout
d’effectuer (c) et (d) dans cet ordre. Dans le cas de l’insertion en tête, on
obtient :

liste

(d)

(b) (c)
(a)
p

L’algorithme est le suivant :


procédure insertavant(var liste : pélément ; elem, val : télément;
var possible : booléen) ;
variable
pval, p : pélément ;
début
pval ← pointeurval(liste, val) ;
20
7 Dr Ndi Nyoungui André
Algorithmique et structures de données

possible ← faux ;
si pval ≠ nil alors
début
possible ← vrai ;
nouveau(p) ;
p^.donnée ← elem ;
p^.suivant ← pval ;
p^.précédent ← pval^.précédent ;
si pval = liste alors
liste ← p
sinon
début
pval^.précédent^.suivant ← p ;
pval^.précédent ← p ;
fin ;
fin ;
fin ;

Insertion après une valeur

Dans le cas général on a quatre pointeurs à modifier :

liste pval

val

(d) (b) (c) (a)

elem
p

L’insertion en tête n’est pas possible, il faut par contre traiter le cas particulier
de l’insertion en fin de liste.

L’algorithme est le suivant :


procédure insertaprès(var liste : pélément ; elem, val : télément;
var possible : booléen) ;
variable
pval, p : pélément ;
début
pval ← pointeurval(liste, val) ;

20
8 Dr Ndi Nyoungui André
Algorithmique et structures de données

possible ← faux ;
si pval ≠ nil alors
début
possible ← vrai ;
nouveau(p) ;
p^.donnée ← elem ;
si pval^.suivant ≠ nil alors
début
p^.suivant ← pval^.suivant ;
pval^.suivant^.précédent ← p ;
p^.précédent ← pval ;
pval^.suivant ← p ;
fin
sinon
début
p^.suivant ← nil ;
p^.précédent ← pval ;
pval^.suivant ← p ;
fin ;
fin ;
fin ;

Insertion à la kème place

On suppose que l’on dispose de la fonction pointeurk qui délivre l’adresse de la


kème cellule, si elle existe, et nil si elle n’existe pas. L’inserion en kème position
revient alors à effectuer une insertion en tête si k = 1 :

liste

(d)

(c)
(a)

(b)
p

20
9 Dr Ndi Nyoungui André
Algorithmique et structures de données

Ou bien une insertion après le (k-1)ème élément, si k > 1 et que cet élément
existe. Il faut prévoir le cas particulier de l’insertion en fin de liste (pk = nil) où
l’action (c) n’a plus de sens.

liste pkmoinsun pk

(d) (b) (c) (a)

L’algorithme est le suivant :


procédure insertionk(var liste : pélément ; elem : télément; k : entier ;
var possible : booléen) ;
variable
p, pk, pkmoinsun : pélément ;
début
possible ← faux ;
si k = 1 alors
début
possible ← vrai ;
nouveau(p) ;
p^.donnée ← elem ;
p^.suivant ← liste ;
p^.précédent ← nil ;
si liste ≠ nil alors
liste^.précédent ← p ;
liste ← p ;
fin
sinon
début
pkmoinsun ← pointeurk(liste, k – 1) ;
si pkmoinsun ≠ nil alors
début
possible ← vrai ;
nouveau(p) ;
p^.donnée ← elem ;
pk ← pkmoinsun^.suivant ;
p^.suivant ← pk ;

21
0 Dr Ndi Nyoungui André
Algorithmique et structures de données

p^.précédent ← pkmoinsun ;
si pk ≠ nil alors
pk^.précédent ← p ;
pkmoinsun^.suivant ← p ;
fin ;
fin ;
fin ;

Insertion après toutes les occurrences

L’algorithme est le suivant :


procédure inseraprèstoutes(var liste : pélément ; elem, val : télément;
var possible : booléen) ;
variable
p, courant : pélément ;
début
courant ← liste ;
possible ← faux ;
tantque courant^.suivant ≠ nil faire
début
si courant^.donnée = val alors
début
possible ← vrai ;
nouveau(p) ;
p^.donnée ← elem ;
p^.suivant ← courant^.suivant ;
p^.précédent ← courant ;
courant^.suivant^.précédent ← p ;
courant^.suivant ← p ;
courant ← p^.suivant ;
fin
sinon
courant ← courant^.suivant ;
fin ;
si courant^.donnée = val alors
début
possible ← vrai ;
nouveau(p) ;
p^.donnée ← elem ;
p^.suivant ← nil ;
p^.précédent ← courant ;
courant^.suivant ← p ;

21
1 Dr Ndi Nyoungui André
Algorithmique et structures de données

fin ;
fin ;

Suppression d’une valeur

On veut supprimer, par exemple, la première occurrence de la valeur val dans une
liste doublement chaînée. On a trois cas possibles : suppression de la première
cellule, suppression de la dernière cellule et le cas général. Supposons que pval
contienne l’adresse de la cellule à supprimer.

Dans le cas général, on a :

pval

(a)
(b)

On peut effectuer les liaisons (a) et (b) dans n’importe quel ordre.

Dans le cas de la suppression en tête, on a deux cas :

• La première cellule est aussi la dernière :

liste

pval

Il suffit d’effectuer l’instruction : liste ← liste^.suivant

• La première cellule n’est pas la dernière :

liste
(a)

(b) 21
2 Dr Ndi Nyoungui André
pval
Algorithmique et structures de données

Il suffit d’effectuer les liaisons (a) et (b).

Dans le cas le cas de la suppression de la dernière cellule, on a aussi deux cas :

• Le dernier est aussi le premier : il suffit de se reporter au cas précédent.


• Le dernier n’est pas le premier : on a alors la situation suivante :

pval

(a)

Il suffit d’effectuer la relation (a).

L’algorithme est alors le suivant :


procédure supprimeval(var liste : pélément ; val : télément; var possible :
booléen) ;
variable
pval : pélément ;
début
possible ← faux ;
pval ← pointeurval(liste, val) ;
si pval ≠ nil alors
début
possible ← vrai ;
si pval = liste alors
liste ← liste^.suivant
sinon
pval^.précédent^.suivant ← pval^.précédent ;
si pval^.suivant ≠ nil alors
pval^.suivant^.précédent ← pval^.précédent ;
fin ;
fin ;

21
3 Dr Ndi Nyoungui André
Algorithmique et structures de données

Suppression de la kème cellule

L’algorithme est identique à celui de la suppression d’une valeur. Il suffit de


remplacer la fonction pointeurval par la fonction pointeurk qui délivre l’adresse
de la kème cellule de la liste si elle existe, et nil si elle n’existe pas.

procédure supprimek(var liste : pélément ; k : entier ; var possible : booléen) ;


variable
pk : pélément ;
début
possible ← faux ;
pk ← pointeurk(liste, val) ;
si pk ≠ nil alors
début
possible ← vrai ;
si pk = liste alors
liste ← liste^.suivant
sinon
pk^.précédent^.suivant ← pk^.précédent ;
si pk^.suivant ≠ nil alors
pk^.suivant^.précédent ← pk^.précédent ;
fin ;
fin ;

Suppression de toutes les occurrences d’une valeur

Il suffit de reprendre et réutiliser la seconde partie de l’algorithme supprime


donnée ci-dessus, pour chacune des occurrences de val dans liste. Afin de rendre
la procédure plus lisible, nous séparons la partie suppression de la partie
recherche de val. On obtient alors :

procédure supprimeptr(var liste : pélément ; p : pélement) ;


début
si p = liste alors
{Suppression en tête de liste}
liste ← liste^.suivant
sinon
{Suppression en cours de liste}
p^.précédent^.suivant ← p^.suivant ;
si p^.suivant ≠ nil alors
{Ce n’était pas le dernier}

21
4 Dr Ndi Nyoungui André
Algorithmique et structures de données

p^.suivant^.précédent ← p^.précédent ;
fin ;

procédure supprimetoutes(var liste : pélément ; val : télément) ;


variable
p : pélément ;
début
p ← liste ;
tantque p ≠ nil faire
début
si p^.donnée = val alors
supprimeptr(liste, p) ;
p ← p^.suivant ;
fin ;
fin ;

Exercice 8.27
Les piles. La structure de pile est une structure de liste particulière.
Contrairement aux fichiers et aux vecteurs, elle ne sert généralement pas à
garder de façon plus ou moins définitive des informations. On s’intéresse plutôt
à la suite des états de la pile et on utilise le fait que le dernier élément ajouté se
trouve au sommet de la pile, afin de pouvoir être atteint le premier.

On peut donner une image du fonctionnement de cette structure avec une pile
d’assiettes : on peut ajouter et enlever des assiettes au sommet de la pile ; toute
insertion ou retrait d’une assiette au milieu de la pile est une opération qui
comporte des risques.

La stratégie de gestion d’une pile est « dernier arrivé, premier servi ». En


anglais on dira « last-in first-out ou en abrégé LIFO”.

Une pile est une liste linéaire telle que :


• les insertions sont toujours effectuées en tête de liste,
• les suppressions sont toujours effectuées en de tête de liste.

La structure de pile est utilisée pour sauvegarder temporairement des


informations en respectant leur ordre d’entrée, et les réutiliser en ordre
inverse. Une pile est liste linéaire, elle peut donc être représentée de façon
contiguë ou chaînée.

1. Écrire une procédure empiler qui a pour effet d’insérer un élément dans la
pile.

21
5 Dr Ndi Nyoungui André
Algorithmique et structures de données

2. Écrire une procédure dépiler qui a pour effet de supprimer l’élément au


sommet de la pile et de retourner sa valeur dans une variable.
3. Écrire une fonction pilevide qui vérifie qu’une pile est vide.
4. Écrire une procédure initpile qui initialise une pile.
5. Écrire une procédure sommetpile qui retourne la valeur de l’élément qui se
trouver au sommet de la pile.

1°/ Représentation contiguë d’une pile

Soit une pile utilisant une représentation contiguë : un vecteur pile dont on donne
a priori la taille maximale taillemax. Dans ce cas, l’accès au premier élément est
déterminé par un indice sommet dont les valeurs extrêmes permettant de tester
les dépassements sont 0 et taillemax. On peut remarquer que la liste est
représentée à l’envers dans le vecteur : la tête de la liste correspond à l’indice le
plus élevé, ou sommet, la base à l’indice 1. Les dépassements sont testés dans les
primitives dépiler et empiler.

Les variables pile, taillemax et sommet étant globales, les primitives de gestion
d’une pile sont les suivantes :

procédure empiler(val : télément) ;


début
si pilepleine alors
écrire(‘la pile est pleine’)
sinon
début
sommet ← sommet + 1 ;
pile[sommet] ← val ;
fin ;
fin ;

procédure dépiler(var val : télément) ;


début
si pilevide alors
écrire(‘la pile est vide’)
sinon
début
val ← pile[sommet] ;
sommet ← sommet - 1 ;
fin ;
fin ;

21
6 Dr Ndi Nyoungui André
Algorithmique et structures de données

procédure sommetpile(var val : télément) ;


début
val ← pile[sommet] ;
fin ;

fonction pilevide : booléen ;


début
pilevide ← sommet = 0 ;
fin ;

fonction pilepleine : booléen ;


début
pilepleine ← sommet = taillemax ;
fin ;

fonction initpilevide : booléen ;


début
sommet = 0 ;
fin ;

2°/ Représentation chaînée d’une pile

Une pile peut être représentée par une liste linéaire chaînée telle que les
insertions ou les suppressions sont toujours effectuées en tête de liste.

La variable pile, de type pélément, étant globale, les primitives deviennent :

fonction pilevide : booléen ;


début
pilevide ← pile = nil ;
fin ;

procédure initpile ;
début
pile = nil ;
fin ;

procédure sommetpile(var elem : télément; var possible : booléen) ;


début
possible ← faux ;
si non pilevide alors

21
7 Dr Ndi Nyoungui André
Algorithmique et structures de données

début
elem ← pile^.donnée ;
possible ← vrai ;
fin ;
fin ;

procédure dépiler(var elem : télément; var possible : booléen) ;


début
si pilevide alors
possible ← faux
sinon
début
elem ← pile^.donnée ;
supptête(pile) ;
fin ;
fin ;

procédure empiler(val : télément) ;


variable
p : pélément ;
début
nouveau(p) ;
p^.donnée ← val ;
p^suivant ← pile
pile ← p ;
fin ;

Exercice 8.28
Les files d’attente ou queues. Une queue est semblable à une file d’attente à
une caisse d’un supermarché. La première personne en ligne est servie en premier
et les autres clients qui entrent à la fin de la queue attendent d’être servis à
leur tour. Les cellules sont retirées uniquement à la tête de la queue et insérés
uniquement à la fin. C’est pourquoi on désigne souvent la queue comme étant une
structure de données « premier arrivé, premier servi ». En anglais on dira
« first-in, first-out ou en abrégé FIFO ».
Les queues ont de nombreuses applications dans les systèmes informatiques. La
plupart des ordinateurs n’ont qu’un seul processeur, de sorte qu’un seul
utilisateur de ce processeur peut être servi à la fois. Les entrées des autres
utilisateurs doivent être placées dans une queue. Chacun des entres avance
progressivement vers le début de la queue, à mesure que les utilisateurs sont

21
8 Dr Ndi Nyoungui André
Algorithmique et structures de données

servis. L’entrée qui se présente à l’avant de la queue est celle qui est sur le point
d’obtenir le service.

Une queue est définie à tout moment par sa tête et par sa queue.

1. Écrire procédure qui initialise une queue.


2. Écrire une procédure ajoutqueue qui permet d’ajouter un élément dans une
queue.
3. Écrire une procédure suppqueue qui permet de supprimer un élément dans
une queue et de retourner la valeur de l’élément supprimer.
4. Écrire une fonction queuevide qui vérifie qu’une queue est vide.

1°/ Représentation contiguë d’une queue

On peut envisager représenter une queue dans un vecteur queue[1..n] simplement


en ajoutant les nouveaux éléments à droite et en déplaçant le pointeur de tête
vers la droite chaque fois que l’on supprime un élément.
En supposant que le vecteur liste[1..n], ainsi que les entiers tête et queue sont
des variables globales, les primitives de gestion d’une queue sont les suivantes :

fonction queuevide : booléen ;


début
queuevide ← tête > queue ;
fin ;

procédure initqueue ;
début
tête ← 1 ;
queue ← 0 ;
fin ;

fonction queuepleine : booléen ;


début
queuepleine ← queue = n ;
fin ;

procédure ajoutqueue(val : télément) ;


début
si non queuepleine alors
début
queue ← queue + 1 ;
liste[queue] ← val ;

21
9 Dr Ndi Nyoungui André
Algorithmique et structures de données

fin
sinon

procédure suppqueue(var val : télément);


début
si non queuevide alors
début
val ← file[tête] ;
tête ← tête + 1 ;
fin ;
fin ;

On voit que les variables tête et queue augmentent toujours, et donc que le
vecteur devra être très grand, même s’il ne contient que peu d’éléments à chaque
instant. Pour contourner cet inconvénient , on peut envisager deux solutions.

a) Décaler les éléments à gauche à chaque suppression

fonction queuevide : booléen ;


début
queuevide ← queue = 0 ;
fin ;

procédure initqueue ;
début
queue ← 0 ;
fin ;

procédure suppqueue(var val : télément) ;


variable
i: entier;
début
si non queuevide alors
début
val ← liste[1] ;
i←1;
tantque i < queue faire
début
liste[i] ← liste[i + 1] ;
i ← i + 1;
fin;

22
0 Dr Ndi Nyoungui André
Algorithmique et structures de données

queue ← queue – 1;
fin ;
fin ;

La taille du vecteur doit correspondre au nombre maximum d’éléments qui


peuvent être simultanément présents dans la queue.

b) Gérer le vecteur de manière circulaire

C’est la meilleure solution, elle minimise la place nécessaire dans le vecteur,


comme dans la solution précédente, tout en évitant les opérations de décalage.

Lorsque tête devient égal à (queue + 1) mod n, la queue est soit vide, soit pleine.
On est donc amené à distinguer les deux possibles en utilisant deux indicateurs
booléens queuevide et queuepleine.

Les primitives deviennent alors :

procédure initqueue ;
début
tête ← 1 ;
queue ← 0 ;
queuevide ← vrai ;
queuepleine ← faux ;
fin ;

procédure ajoutqueue(val : télément);


variable
i: entier;
début
si non queuevide alors
si queue < n alors
queue ← queue + 1
sinon
début
queue ← 1 ;
liste[queue] ← val ;
queuevide ← faux ;
queuepleine ← ((queue < n) et (tête = queue + 1))
ou ((queue = n) et (tête = 1)) ;
fin ;

22
1 Dr Ndi Nyoungui André
Algorithmique et structures de données

fin ;

procédure suppqueue(val : télément);


début
si non queuevide alors
début
val ← liste[tête] ;
si tête < n alors
tête ← tête + 1
sinon
début
tête ← 1 ;
queuepleine ← faux ;
queuevide ← ((queue < n) et (tête = queue + 1))
ou ((queue = n) et (tête = 1)) ;
fin ;
fin ;
fin ;

2°/ Représentation chaînée d’une queue

C’est une représentation classique de liste chaînée, dans laquelle on utilise une
pointeur supplémentaire : le pointeur sur la dernier cellule, ce qui permet
d’accélérer l’algorithme d’insertion qui a toujours en fin de liste.

En supposant que les variables tête et queue sont globales, les primitives de
gestion d’une queue deviennent :

fonction queuevide : booléen ;


début
queuevide ← (tête = nil) et (queue = nil) ;
fin ;

procédure initqueue ;
début
tête ← nil ;
queue ← nil ;
fin ;

procédure ajoutqueue(val : télément);


début

22
2 Dr Ndi Nyoungui André
Algorithmique et structures de données

si tête = nil alors


début
insertête(tête, val) ;
queue ← tête ;
fin
sinon
début
insertête(queue^.suivant, val) ;
queue ← queue^.suivant ;
fin ;
fin ;

procédure suppqueue(var val : télément);


début
si tête ≠ nil alors
début
val ← tête^.donnée ;
supptête(tête) ;
si tête = nil alors
queue ← nil ;
fin ;
fin ;

Études de cas

Dans ces études de cas, nous appliquerons les algorithmes classiques sur les
listes chaînées à quelques structures de données complexes.

Bibliothèque

On souhaite gérer le stock des livres d’une bibliothèque universitaire. Pour


chaque ouvrage les informations retenues sont le nom de l’auteur, le nom de
l’éditeur, le titre de l’ouvrage, la discipline et l’année d’édition.

Les structures de données utilisées sont les suivantes :

type
pouvrage = ^touvrage ;
touvrage = article
auteur : chaîne ;
éditeur : chaîne ;

22
3 Dr Ndi Nyoungui André
Algorithmique et structures de données

titre : chaîne ;
discipline : chaîne ;
année : entier ;
suivant : pouvrage ;
fin ;

On suppose que tous les auteurs ont des noms différents.

1°/ Écrire un algorithme pour créer une liste chaînée d’ouvrages à partir d’un
fichier.

Nous écrivons d’abord des procédures auxiliaires pour lire un article de type
ouvrage et créer un fichier séquentiel d’articles de type ouvrage.

procédure lireouvrage(var livre : pouvrage) ;


variable
choix : entier ;
début
écrire('Auteur : ') ;
lireln(livre.auteur) ;
écrire('Editeur : ') ;
lireln(livre.éditeur) ;
écrire('Titre : ') ;
lireln(livre.titre) ;
écrire('Discipline : ') ;
lireln(livre.discipline) ;
écrire('Année édition : ') ;
lireln(livre.année) ;
fin ;

procédure créerfichier(nomfichier : chaîne) ;


variable
stop : booléen ;
choix : entier ;
livre : ouvrage ;
f : fichier de ouvrage ;
début
réécrire(f, nomdichier) ;
stop ← faux ;
tantque non stop faire
début

22
4 Dr Ndi Nyoungui André
Algorithmique et structures de données

écrire('Voulez-vous continuer (0 : Quitter 1 : Continuer)') ;


lireln(choix) ;
si choix = 1 alors
début
lireouvrage(livre)
écrire(f, livre) ;
fin
sinon
stop ← vrai ;
fin ;
fermer(f);
fin ;

procédure créerliste(var liste : pouvrage ; nomfichier : chaîne) ;


variable
dernier, courant : pouvrage ;
f : fichier de touvrage ;
début
relire(f, nomfichier) ;
dernier ← nil ;
dernier ← liste ;
tantque non fin(f) faire
début
nouveau(courant) ;
lire(f, courant^) ;
courant^.suivant ← dernier ;
dernier ← courant ;
fin ;
liste ← dernier ;
fermer(f) ;
fin ;

2°/ Écrire , sous forme itérative et sous forme récursive, un algorithme qui
imprime le nom de l’auteur, le nom de l’éditeur, le titre de l’ouvrage, la discipline
et l’année d’édition de tous les ouvrages enregistrés.

Nous écrivons d’abord une procédure auxiliaire pour imprimer un article de type
ouvrage.

procédure écrireouvrage(livre : ouvrage) ;


début

22
5 Dr Ndi Nyoungui André
Algorithmique et structures de données

écrireln('Auteur : ', livre.auteur) ;


écrireln('Editeur : ', livre.éditeur) ;
écrireln('Titre : ', livre.titre) ;
écrireln('Discipline : ', livre.discipline) ;
écrireln('Année édition : ', livre.année) ;
fin ;

Version itérative

procédure écrirelistegd(liste : pouvrage) ;


variable
courant : pouvrage ;
début
courant ← liste ;
tantque courant ≠ nil faire
début
écrireouvrage(courant^) ;
courant ← courant^.suivant ;
fin ;
fin ;

Version récursive

procédure écrirelistegdrec(liste : pouvrage) ;


début
si liste ≠ nil alors
début
écrireouvrage(liste^) ;
écrirelistegdrec(liste^.suivant) ;
fin ;
fin ;

3°/ Écrire, sous forme itérative et sous forme récursive, une fonction retourne
le nombre d’ouvrages présents dans la liste.

Version itérative

fonction longueurliste(liste : pouvrage) : entier ;


variable
courant : pouvrage ;
compte : entier ;

22
6 Dr Ndi Nyoungui André
Algorithmique et structures de données

début
courant ← liste ;
compte ← 0 ;
tantque courant ≠ nil faire
début
compte ← compte + 1 ;
courant ← courant^.suivant ;
fin ;
longueurliste ← compte ;
fin ;

Version récursive

fonction longueurliste(liste : pouvrage) : entier ;


début
si liste = nil alors
longueurliste ← 0
sinon
longueurliste ← 1 + longueurliste(liste^.suivant) ;
fin ;

4°/ Écrire, sous forme itérative et sous forme récursive, une fonction qui
retourne le nombre d’ouvrages écrits par un auteur donné.

Version itérative

fonction nbouvrages(liste : pouvrage ; nomauteur : chaîne) : entier ;


variable
liste1 : pouvrage ;
compte : entier ;
début
liste1 ← liste ;
compte ← 0 ;
tantque liste1 ≠ nil faire
début
si liste1^.auteur = nomauteur alors
compte ← compte + 1 ;
courant ← courant^.suivant ;
fin ;
nbouvrages ← compte ;
fin ;

22
7 Dr Ndi Nyoungui André
Algorithmique et structures de données

Version récursive

fonction nbouvrages(liste : pouvrage ; nomauteur : chaîne) : entier ;


début
si liste = nil faire
nbouvrages ← 0
sinon
si liste^.auteur = nomauteur alors
nbouvrages ← 1 + nbouvrages(liste^.suivant, nomauteur)
sinon
nbouvrages ← nbouvrages(liste^.suivant, nomauteur) ;
fin

5°/ Écrire, sous forme itérative et sous forme récursive, une fonction qui
retourne un pointeur sur la kème cellule de la liste. La fonction retourne nil si la
cellule de rang k n’existe pas dans la liste.

Version itérative

fonction pointeurk(liste : pouvrage ; k : entier) : pouvrage;


variable
courant : pouvrage ;
i : entier ;
début
courant ← liste ;
i←1;
tantque (i < k) et (courant ≠ nil) faire
début
i←i+1;
courant ← courant^.suivant ;
fin ;
si courant ≠ nil alors
pointeurk ← courant
sinon
pointeurk ← nil;
fin ;

Version récursive

fonction pointeurk(liste : pouvrage ; k : entier) : pouvrage;

22
8 Dr Ndi Nyoungui André
Algorithmique et structures de données

début
si (liste = nil) alors
pointeurk ← liste
sinon
si (k = 1) alors
pointeurk ← liste
sinon
pointeurk ← pointeurk(liste^.suivant, k-1);
fin ;

6°/ Écrire, sous forme itérative et sous forme récursive, une fonction qui
retourne un pointeur sur le dernier livre d’une discipline donnée contenu dans une
liste. La fonction retourne nil si aucun live de mathématiques ne figure dans la
liste.

Version itérative

fonction pointeurdernier(liste : pouvrage ; discip : chaîne) : pouvrage ;


variable
liste1, ptd : pouvrage ;
début
liste1 ← liste ;
ptd ← nil ;
tantque liste1 ≠nil faire
début
si liste1^.discip = discipline alors
ptd ← liste1 ;
liste1 ← liste1^.suivant ;
fin ;
pointeurdernier ← ptd ;
fin ;

Version récursive

fonction pointeurdernier(liste : pouvrage ; discip : chaîne ; var ptd : pouvrage) :


pouvrage ;
début
si liste = nil alors
pointeurdernier ← ptd
sinon
si liste^.discipline = discip alors

22
9 Dr Ndi Nyoungui André
Algorithmique et structures de données

début
ptd ← liste ;
pointeurdernier ← pointeurdernier(liste^.suivant,
discip, ptd) ;
fin
sinon
pointeurdernier ← pointeurdernier(liste^.suivant, discip, ptd)
fin ;

7°/ On suppose que la liste est triée par ordre alphabétique sur les noms des
auteurs. Écrire, sous forme itérative et sous forme récursive, une fonction qui
délivre un pointeur sur le premier ouvrage écrit par un auteur donné. La fonction
retourne nil si cet auteur ne figure pas dans la liste.

Version itérative

ponction premièrefois(liste : pouvrage ; nomauteur) : pouvrage ;


variable
liste1 : pouvrage ;
début
liste1 ← liste ;
tantque (liste1 ≠ nil) et alors (liste^.auteur < nomauteur) faire
liste1 ← liste1^.suivant ;
si (liste1 = nil) ou sinon (liste1^.auteur = nomauteur) alors
premièrefois ← liste1
sinon
premièrefois ← nil ;
fin ;

Version récursive

ponction premièrefois(liste : pouvrage ; nomauteur) : pouvrage ;


début
si liste = nil alors
premièrefois ← nil
sinon
si liste^.auteur < nomauteur alors
premièrefois ← premièrefois(liste^.suivant, nomauteur)
sinon
si liste^.auteur > nomauteur alors
premièrefois ← nil

23
0 Dr Ndi Nyoungui André
Algorithmique et structures de données

sinon
premièrefois ← liste ;
fin ;

8°/ On suppose que la liste est triée par ordre alphabétique sur les noms des
auteurs. Écrire, sous forme itérative et sous forme récursive, une fonction qui
délivre un pointeur sur le dernier ouvrage écrit par un auteur donné. La fonction
retourne nil si cet auteur ne figure pas dans la liste.

Version itérative

ponction dernièrefois(liste : pouvrage ; nomauteur) : pouvrage ;


variable
liste1, dernier : pouvrage ;
début
liste1 ← liste ;
dernier ← nil ;
tantque (liste1 ≠ nil) et alors (liste^.auteur ≤ nomauteur) faire
début
si liste1^.auteur = nomauteur alors
dernier ← liste1 ;
liste1 ← liste1^.suivant
fin ;
dernièrefois ← dernier ;
fin ;

Version récursive

ponction premièrefois(liste : pouvrage ; nomauteur) : pouvrage ;


début
si liste = nil alors
premièrefois ← nil
sinon
si liste^.auteur < nomauteur alors
premièrefois ← premièrefois(liste^.suivant, nomauteur)
sinon
si liste^.auteur > nomauteur alors
premièrefois ← nil
sinon
premièrefois ← liste ;
fin ;

23
1 Dr Ndi Nyoungui André
Algorithmique et structures de données

9°/ Écrire, sous forme itérative et sous forme récursive, une procédure qui
insère un ouvrage à la kème place dans la liste.

Nous écrivons d’abord la procédure auxiliaire insertête.

procédure insertête(var liste : pouvrage ; livre : ouvrage) ;


variable
courant : pouvrage ;
début
nouveau(courant) ;
courant^.auteur ← livre.auteur ;
courant^.éditeur ← livre.éditeur ;
courant^.titre ← livre.titre ;
courant^.discipline ← livre.discipline ;
courant^.année ← livre.année ;
courant^.suivant ← liste ;
liste ← courant ;
fin ;

Version itérative

procédure insertionk(var liste : pouvrage ; k : entier ;


livre : ouvrage ; var possible : booléen) ;
variable
précédent : pouvrage ;
début
si (k = 1) alors
début
insertête(liste, livre) ;
possible ← vrai ;
fin
sinon
début
précédent ← pointeurk(liste, k-1) ;
si (précédent = nil) alors
possible ← faux
sinon
début
insertête(précédent^.suivant, livre) ;
possible ← vrai ;

23
2 Dr Ndi Nyoungui André
Algorithmique et structures de données

fin ;
fin ;
fin ;

Version récursive

procédure insertionkrec(var liste : pouvrage ; k : entier ;


livre : ouvarge ; var possible : booléen) ;
variable
précédent : pouvrage ;
début
si (k = 1) alors
début
insertête(liste, livre) ;
possible ← vrai ;
fin
sinon
si (liste = nil) alors
possible ← faux
sinon
insertionkrec(liste^.suivant, k-1, livre, possible) ;
fin ;

10°/ Écrire, sous forme itérative et sous forme récursive, un algorithme


d’insertion d’un ouvrage après le premier ouvrage d’une discipline donnée
rencontré dans la liste.

Nous écrivons d’abord une fonction auxiliaire qui délivre un pointeur sur le
premier ouvrage d’une discipline donnée rencontré dans la liste.

Version itérative

fonction pointeurdiscip(liste : pouvrage ; discip : chaîne) : pouvrage ;


variable
courant : pouvrage ;
trouvé : booléen ;
début
courant ← liste ;
trouvé ← faux ;
tantque (non trouvé ) et (courant ≠ nil) faire
début

23
3 Dr Ndi Nyoungui André
Algorithmique et structures de données

si courant^.discipline = discip alors


trouvé ← faux
sinon
courant ← courant^.suivant ;
fin ;
si trouvé alors
pointeurdiscip ← courant
sinon
pointeurdiscip ← nil;
fin ;

Version récursive

fonction pointeurdiscip(liste : pouvrage; discip: chaîne) : pouvrage ;


début
si liste = nil alors
pointeurdiscip ← liste
sinon
si liste^.discipline = discip alors
pointeurdiscip ← liste
sinon
pointeurdiscip ← pointeurdiscip(liste^.suivant, discip)
fin ;

Version itérative

procédure insertaprès(liste : pouvrage ; livre : ouvrage ;


discip : chaîne ; var possible : booléen) ;
variable
liste1 : pouvrage ;
début
liste1 ← pointeurdiscip(liste, discip) ;
si liste1 = nil alors
possible ← faux
sinon
début
possible ← vrai ;
insertête(liste1^.suivant, livre) ;
fin ;
fin ;

23
4 Dr Ndi Nyoungui André
Algorithmique et structures de données

Version récursive

procédure insertaprès(liste : pouvrage ; livre : ouvrage ;


discip : chaîne ; var possible : booléen) ;
début
si (liste = nil) alors
possible ← faux
sinon
si (liste^.discipline = discip) alors
début
possible ← vrai ;
insertête(liste^.suivant, livre) ;
fin ;
sinon
insertaprès(liste^.suivant, livre, discip, possible) ;
fin ;

11°/ Écrire sous forme itérative un algorithme d’insertion d’un ouvrage avant le
premier ouvrage d’une discipline donnée rencontré dans la liste.

Version récursive

procédure insertavant(liste : pouvrage ; livre : ouvrage ; discip : chaîne ;


var possible : booléen) ;
début
si liste = nil alors
possible ← faux
sinon
si liste^.discipline = discip alors
début
possible ← vrai ;
insertête(liste, livre) ;
fin
sinon
insertavant(liste^.suivant, livre, discip, possible) ;
fin ;

Version itérative

procédure insertavant(liste : pouvrage ; livre : ouvrage ; discip : chaîne ;


var possible : booléen) ;

23
5 Dr Ndi Nyoungui André
Algorithmique et structures de données

variable
p : pouvrage ;
début
si liste = nil alors
possible ← faux
sinon
si liste^.discipline = discip alors
début
possible ← vrai ;
insertête(liste, livre) ;
fin
sinon
début
p ← liste ;
tantque (p^.suivant ≠ nil) et alors
(p^.suivant^.discipline ≠ discip)
faire
p ← p^.suivant ;

si p^.suivant ≠ nil alors


insertête(p^.suivant, livre) ;
fin ;
fin ;

12°/ On suppose que la liste est trié par ordre alphabétique sur les noms des
auteurs. Écrire, sous forme itérative et sous forme récursive, une procédure
d’insertion d’un ouvrage dans la liste.

Version itérative

procédure insertrié(var liste : pouvrage ; livre : ouvrage) ;


variable
courant, précédent : pouvrage ;
début
si (liste = nil) ou sinon (livre.auteur ≤ liste^.auteur) alors
insertête(liste, livre)
sinon
début
précédent ← liste ;
courant ← liste^.suivant ;

23
6 Dr Ndi Nyoungui André
Algorithmique et structures de données

tantque (courant ≠ nil) et alors (livre.auteur >


courant^.auteur) faire
début
précédent ← courant ;
courant ← courant^.suivant ;
fin ;
insertête(précédent^.suivant, livre) ;
fin ;
fin ;

Version récursive

procédure insertrié(var liste : pouvrage ; livre : ouvrage) ;


début
si (liste = nil) ou sinon (liste^.auteur ≤ livre.auteur) alors
insertête(liste, livre)
sinon
insertrié(liste^.suivant, livre) ;
fin ;

13°/ Écrire un algorithme de suppression du kème ouvrage enregistré dans de la


liste.

Nous écrivons d’abord la procédure auxiliaire de suppression en tête de liste.

procédure supprimetête(var liste : pouvrage) ;


variable
courant : pouvrage ;
début
courant ← liste ;
liste ← liste^.suivant ;
libérer(courant);
fin ;

Version itérative

procédure supprimek(var liste : pouvrage ; k : entier ; var possible : booléen) ;


variable
précédent : pouvrage ;
début
si (liste ≠ nil ) et (k = 1) alors

23
7 Dr Ndi Nyoungui André
Algorithmique et structures de données

début
supprimetête(liste) ;
possible ← vrai ;
fin
sinon
début
possible ← faux ;
précédent ← pointeurk(liste, k-1) ;
si (précédent ≠ nil) et alors (précédent^.suivant ≠ nil) alors
début
possible ← vrai ;
supprimetête(précédent^.suivant)
fin ;
fin ;
fin ;

Version récursive

procédure supprimek(var liste : pouvrage ; k : entier ; var possible : booléen) ;


début
si (liste = nil) alors
possible ← faux
sinon
si (k = 1) alors
début
possible ← vrai ;
supprimetête(liste) ;
fin
sinon
supprimek(liste^.suivant, k - 1, possible)
fin ;

14°/ Écrire, sous forme itérative et sous forme récursive, une procédure de
suppression du premier titre d’une discipline donné contenus dans la liste.

Version récursive

procédure suppouvrage(var liste : pouvrage ; discip : chaîne ; var possible :


booléen) ;
début
si (liste ≠ nil) alors

23
8 Dr Ndi Nyoungui André
Algorithmique et structures de données

possible ← faux
sinon
si (liste^.discipline = discip) alors
début
supprimetête(liste) ;
possible ← vrai;
fin
sinon
supprimeval(liste^.suivant, val, possible) ;
fin ;

procédure suppouvrage(var liste : pouvrage ; discip : chaîne ; var possible :


booléen) ;
variable
p : pouvrage ;
début
possible ← faux ;
si (liste ≠ nil) alors
si (liste^.discipline = discip) alors
début
supprimetête(liste) ;
possible ← vrai;
fin
sinon
début
possible ← faux;
p ← liste ;
tantque (p ≠ nil) et alors (p^.suivant^.discipline ≠
discip) faire
p ← p^.suivant ;

si (p^.suivant ≠ nil) et alors


(p^.suivant^.discipline = discip)
alors
début
possible ← vrai ;
supprimetête(p^.suivant) ;
fin ;
fin ;
fin ;

23
9 Dr Ndi Nyoungui André
Algorithmique et structures de données

15°/ Écrire un algorithme de suppression de tous les livres écrits par un auteur
donné contenus dans la liste.

Version itérative

procédure supprimetoutes(var liste : pouvrage ; nomauteur: chaîne) ;


variable
précédent, courant : pouvrage ;
début
tantque (liste ≠ nil) et alors (liste^.auteur = nomauteur) faire
début
précédent ← liste ;
courant ← précédent^.suivant ;
tantque courant ≠ nil faire
début
si liste^.donnée = elem alors
supptête(précédent^.suivant) ;
sinon
précédent ← courant ;
courant ← précédent^.suivant ;
fin ;
fin ;
fin ;

Version récursive

procédure supprimetoutes(var liste : POINTEUR ; nomauteur : chaîne) ;


début
si liste ≠ nil alors
si liste^.auteur = nomauteur alors
début
supptête(liste) ;
supprime(liste, elem) ;
fin
sinon
supprimetoutes(liste^.suivant, nomauteur) ;
fin ;

Agence de voyage

24
0 Dr Ndi Nyoungui André
Algorithmique et structures de données

On souhaite automatiser la gestion des réservations dans une agence de voyage


qui offre des prestations dans le domaine du transport aérien. L’agence travaille
pour cela avec un certain nombre de compagnies aériennes. Les structures de
données utilisées sont les suivantes :

1. Une liste chaînée des compagnies avec lesquelles l’agence travaille. Chaque
compagnie sera caractérisée par :
• le nom de la compagnie
• un pointeur sur la liste des vols offerts par cette compagnie.

2. Pour chaque compagnie, il existe une liste chaînée des vols prévus. Chaque vol
est caractérisé par :
• le numéro du vol,
• les villes de départ et de destination,
• les heures de départ et d’arrivée,
• le nombre de places,
• un vecteur de booléens pour gérer la disponibilité des places.
• un pointeur sur une liste de passagers ayant fait une réservation pour ce
vol,

3. Pour chaque vol, il existe une liste chaînée des passagers ayant fait une
réservation. Chaque passager est caractérisé par :
• le nom du passager,
• le numéro du vol,
• le numéro de siège.

Les déclaration utilisées sont les suivantes :

type
pcompagnie = ^tcompagnie ;
ppassager = ^ppassager ;
pvol = ^tvol ;
tcompagnie = article
nomcomp : chaîne ;
listevols : pvol ;
suivant : pcompagnie ;
fin ;
tvol = article
numéro : chaîne ;
villedépart, villearrivée : chaîne ;
heuredépart, heurearrivée : entier ;

24
1 Dr Ndi Nyoungui André
Algorithmique et structures de données

nbplaces : entier ;
listeplaces : vecteur[1..nbplaces] de booléen ;
listepass : ppassager ;
suivant : pvol ;
fin ;
ppassager = article
nompass : chaîne ;
numvol : chaîne ;
siège : entier ;
suivant : ppassager ;
fin ;

On supposera que :

• tous les vols ont des numéros différents.


• toutes les compagnies ont des noms différents.
• le nombre des passagers pour un vol est limité par le nombre de places
disponibles.
• le nombre vols proposés par une compagnie est illimité.
• la liste des compagnies est ordonnée par ordre alphabétique sur les noms
des compagnies.

Parcours de liste et comptage d’éléments

1°/ Écrire, sous itérative et sous forme récursive, une fonction qui retourne le
nombre de compagnies qui n’ont pas de vol programmé.

2°/ Écrire, sous itérative et sous forme récursive, une fonction qui retourne le
nombre de compagnies ayant un seul vol programmé.

3°/ Écrire, sous itérative et sous forme récursive, une fonction qui retourne le
nombre total de vols programmés.

4°/ Écrire, sous itérative et sous forme récursive, une fonction qui retourne le
nombre de vols programmés par la compagnie de nom nomcomp.

5°/ Un crash s’est produit. On désire connaître le nom de la compagnie


concernée. Écrire une fonction qui retourne un pointeur sur la compagnie
concernée.

24
2 Dr Ndi Nyoungui André
Algorithmique et structures de données

Mises à jour d’éléments

6°/ Écrire une procédure qui enregistre un passager de nom nompassager dans le
vol de numéro numvol de la compagnie de nom nomcomp.

7°/ On suppose maintenant que la liste de passagers pour chaque vol est
ordonnée par ordre alphabétique. Écrire une procédure qui enregistre un
passager de nom nompassager dans le vol de numéro numvol de la compagnie de
nom nomcomp.

8°/ Écrire une procédure qui supprimer le passager de nom nompassager dans le
vol de numéro numvol de la compagnie de nom nomcomp.

9°/ Écrire une procédure qui transfère le passager de nom nompassager du vol
de numéro numvil1 au vol de numéro numvol2 de la compagnie de nom nomcomp.

Familles

On souhaite gérer une population composée de plusieurs familles limitées à deux


générations. Dans un premier temps, on se limitera à des familles composées
uniquement du nom de famille. Dans un deuxième temps, les parents, les enfants
et les voitures possédées par une famille.

Première partie : Liste à un seul niveau

La liste est ordonnée par ordre alphabétique sur les noms de famille. La
population correspond au schéma suivant :

liste

Hamado
Amougou Kamgang
u

On dispose des définitions suivantes :

type
pfamille = ^tfamille ;
tfamille = article
nom : chaîne ;
suivant : pfamille ;

24
3 Dr Ndi Nyoungui André
Algorithmique et structures de données

fin ;

1°/ Écrire, sous forme itérative et sous forme récursive, une fonction retourne
le nombre de familles dans une liste.

Version itérative

fonction nbfamillesliste : pfamille) : entier


variable
courant : pfamille ;
compte : entier ;
début
courant ← liste ;
compte← 0 ;
tantque courant ≠ nil faire
début
compte ← compte + 1 ;
courant ← courant^suivant ;
fin ;
nbfamilles← compte ;
fin ;

Version récursive

fonction nbfamillesliste : pfamille) : entier


début
si liste = nil alors
nbfamille ← 0
sinon
nbfamilles← 1 + nbfamillesliste^.suivant) ;
fin ;

2°/ Écrire, sous forme itérative et sous forme récursive, une fonction qui
détermine si une famille de donnée est présente dans la liste.

Version itérative

fonction présent(liste : pfamille ; nomfam : chaîne) : pfamille ;


variable
courant : pfamille ;

24
4 Dr Ndi Nyoungui André
Algorithmique et structures de données

début
courant ← liste ;
tantque (courant ≠ nil) et alors (nomfam > liste^.nom) faire
courant ← courant^.suivant ;
si (courant ≠ nil) et alors (courant^.nom = nomfam) alors
présent ← courant
sinon
présent ← nil ;
fin ;

Version itérative

fonction présent(liste : pfamille ; nomfam : chaîne) : pfamille ;


début
si (liste = nil) ou sinon (liste^.nom > nomfam) alors
présent ← nil
sinon
si liste^.nom = nomfam alors
présent ← liste
sinon
présent ← présent(liste^.suivant) ;
fin ;

3°/ Écrire, sous forme itérative et sous forme récursive, une procédure qui
insère une nouvelle famille dans la liste.

Il s’agit d’une insertion classique dans une liste chaînée. On définit d’abord la
procédure auxiliaire insertête.

procédure insertête(var liste : pfamille ; nomfam : chaîne) ;


variable
p : pfamille ;
début
nouveau(p) ;
p^.nom ← nomfam ;
p^.suivant ← liste ;
liste ← p ;
fin ;

Version itérative

24
5 Dr Ndi Nyoungui André
Algorithmique et structures de données

procédure insertion(var liste : pfamille ; nomfam : chaîne) ;


variable
précédent, courant : pfamille ;
égal, super : booléen ;
début
si (liste = nil) ou sinon (liste^.nom > nomfam) alors
insertête(liste, nomfam)
sinon
début
courant ← liste ;
super ← vrai ;
égal ← faux ;
tantque (courant ≠ nil) et super faire
si nomfam > courant^.nom alors
début
précédent ← courant ;
courant ← courant^.suivant ;
fin
sinon
début
super ← faux ;
égal ← nomfam = courant^.nom ;
fin ;
si non égal alors
insertête(précédent^.suivant, nomfam) ;
fin ;
fin ;

Version récursive

procédure insertion(var liste : pfamille ; nomfam : chaîne) ;


début
si (liste = nil) ou sinon (nomfam < liste^.nom) alors
insertête(liste, nomfam)
sinon
si nomfam > liste^.nom alors
insertion(liste^.suivant, nomfam) ;
fin ;

4°/ Écrire, sous forme itérative et sous forme récursive, une procédure qui
supprime une famille de nom donné de la liste.

24
6 Dr Ndi Nyoungui André
Algorithmique et structures de données

Il s’agit d’une suppression classique dans une liste triée. On définit d’abord la
procédure auxiliaire supptête.

procédure supptête(var liste : pfamille) ;


variable
p : pfamille ;
début
p ← liste ;
liste ← liste^.suivant ;
libérer(p) ;
fin ;

Version itérative

procédure supprime(var liste : pfamille ; nomfam : chaîne) ;


variable
courant : pfamille ;
infer : booléen ;
début
si liste ≠ nil alors
si liste^.nom = nomfam alors
supptête(liste)
sinon
début
infer ← vrai ;
courant ← liste ;
tantque (courant^.suivant ≠ nil) et infer faire
si courant^.suivant^.nom ≥ nomfam alors
début
infer ← faux ;
si nomfam = courant^.suivant^.nom
alors
supptête(courant^.suivant ;
fin
sinon
courant courant^.suivant ;
fin ;
fin ;

Deuxième partie : liste à plusieurs niveaux

24
7 Dr Ndi Nyoungui André
Algorithmique et structures de données

On considère une population composée de plusieurs familles. En général, une


famille est composée de deux parents et d’un ou plusieurs enfants.
On peut avoir aussi les cas particuliers suivants :
• un seul parent (pas de conjoint et pas d’enfant),
• un seul parent et un ou plusieurs enfants,
• aucun parent, mais un ou plusieurs enfants (cas du décès des deux
parents),
• deux parents, mais pas d’enfants,
• une personne (parent ou enfant) appartient à une seule famille,
• à chaque famille, on associe la liste des voitures, en nombre illimité,
possédées par les membres de la famille.

type
pfamille = ^tfamille ;
ppersonne = ^tpersonne ;
pvoiture = ^tvoiture ;
tfamille = article
nom : chaîne ;
parent : ppersonne ;
enfant : ppersonne ;
voiture : pvoiture ;
suivant : pfamille ;
fin ;
tpersonne = article
nom : chaîne ;
sexe : caractère ;
suivant : ppersonne ;
fin ;
tvoiture = article
marque : chaîne ;
numéro : chaîne ;
suivant : pvoiture ;
fin ;

On supposera que :

• toutes les familles ont des numéros différents


• tous les enfants d’une même famille ont des noms différents.
• le nombre de parents est limité à deux.
• le nombre des enfants est illimité.

24
8 Dr Ndi Nyoungui André
Algorithmique et structures de données

• la population est ordonnée par ordre alphabétique sur les noms de famille.

Parcours de liste et comptage d’éléments

1°/ Écrire, sous itérative et sous forme récursive, une fonction qui retourne le
nombre de famille sans parents.

Version itérative

fonction nbfamillesansparent(liste : pfamille) : entier ;


variable
liste1 : pfamille ;
compte : entier ;
début
liste1 ← liste ;
compte ← 0 ;
tantque liste1 ≠ nil faire
début
si liste1^.parent = nil alors
compte ← compte + 1 ;
liste1 ← liste1^.suivant ;
fin ;
nbfamillesansparent ← compte ;
fin ;

Version récursive

fonction nbfamillesansparent(liste : pfamille) : entier ;


début
si liste = nil alors
nbfamillesansparent ← 0
sinon
si liste^.parent = nil alors
nbfamillesansparent ← 1 + nbfamillesansparent(liste^.suivant)
sinon
nbfamillesansparent ← nbfamillesansparent(liste^.suivant) ;
fin ;

2°/ Écrire, sous itérative et sous forme récursive, une fonction qui retourne le
nombre de familles qui n’ont plus qu’un seul parent.
Version récursive

24
9 Dr Ndi Nyoungui André
Algorithmique et structures de données

fonction parentseul(liste : pfamille) : entier ;


début
si liste = nil alors
parentseul ← 0
sinon
si (liste^.parent = nil) ou sinon (liste^.parent^.suivant ≠ nil) alors
parentseul ← parentseul(liste^.suivant)
sinon
parentseul ← 1 + parentseul(liste^.suivant) ;
fin ;

3°/ Écrire, sous itérative et sous forme récursive, une fonction qui retourne le
nombre d’enfants de la population.

Version itérative

fonction nbenfants(liste : pfamille) : entier ;


variable
liste1 : pfamille ;
enf : ppersonne ;
compte : entier ;
début
liste1 ← liste ;
compte ← 0 ;
tantque liste1 ≠ nil faire
début
enf ← liste^.enfant ;
tantque enf ≠ nil faire
début
compte ← compte + 1 ;
enf ← enf^.suivant ;
fin ;
liste1 ← liste1^.suivant ;
fin ;
nbenfants ← compte ;
fin ;

Version récursive

fonction nbenfantsfamille(enf : ppersonne) : entier ;

25
0 Dr Ndi Nyoungui André
Algorithmique et structures de données

début
si enf = nil alors
nbenfantsfamille ← 0
sinon
nbenfantsfamille ← 1 + nbenfantsfamille(enf^.suivant) ;
fin ;

fonction nbenfants(liste : pfamille) : entier ;


début
si liste = nil alors
nbenfants ← 0
sinon
nbenfants ← nbenfantsfamille(liste^.enfant) +
nbenfants(listesuivant) ;
fin ;

4°/ Écrire, sous itérative et sous forme récursive, une fonction qui retourne le
nombre d’enfants d’une famille de nom donné.

Version itérative

fonction nbenfantsfammille(liste : pfamille ; nomfam : chaîne) : entier ;


variable
fam : pfamille ;
enf : ppersonne ;
compte : entier ;
début
fam ← présent(liste, nomfam) ;
compte ← 0 ;
si fam ≠ nil alors
début
enf ← fam^.enfant ;
tantque enf ≠ nil alors
début
compte ← compte + 1 ;
enf ← enf^.suivant ;
fin ;
fin ;
nbenfantsfamille ← compte ;
fin ;

25
1 Dr Ndi Nyoungui André
Algorithmique et structures de données

5°/ Un vol de voiture a eu lieu. On désire connaître le propriétaire de la voiture.


Écrire une fonction qui retourne un pointeur sur le propriétaire d’une voiture de
numéro donné.

On décompose l’algorithme en deux fonctions récursives : l’une présentvoiture


effectue le parcours des voitures de la famille, l’autre famillevoiture effectue le
parcours de familles en faisant appel à présentvoiture.

fonction présentvoiture(voit : pvoiture ; numéro : chaîne) : booléen ;


début
si voit = nil alors
présentvoiture ← faux
sinon
si voit^.numéro = numéro alors
présentvoiture ← vrai
sinon
présentvoiture ← présentvoiture(voit^.suivant, numéro) ;
fin ;

fonction famillevoiture(liste : pfamille ; numéro : chaîne) : pfamille ;


début
si (liste = nil) ou sinon (présentvoiture(liste^.voiture, numéro) alors
famillevoiture ← liste
sinon
famillevoiture ← famillevoiture(liste^.suivant, numéro) ;
fin ;

Mises à jour d’éléments

6°/ Écrire une procédure qui insère un enfant de prénom et de sexe donnés dans
une famille de nom donné.

On défint d’abord la procédure auxiliaire insertête.

procédure insertête(var enf : pfamille ; prénom : chaîne ; sexe : caractère) ;


variable
p : ppersonne ;
début
nouveau(p) ;
p^.prénom ← prénom ;
p^.sexe ← sexe ;

25
2 Dr Ndi Nyoungui André
Algorithmique et structures de données

p^.suivant ← enf ;
enf ← p ;
fin ;

procédure nouvellenaissance(liste : pfamille ; nomfam, prénom : chaîne ; sexe :


caractère) ;
variable
liste1 : pfamille ;
début
liste1 ← présent(liste, nomfam) ;
si liste1 ≠ nil alors
insertête(liste1^.enfant, prénom, sexe) ;
fin ;

7°/ On suppose maintenant que la liste des enfants est ordonnée par ordre
alphabétique. Écrire une procédure qui insère un enfant de nom et de sexe
donnés dans une famille de nom donné.

procédure insertenfant(var enf : pfamille ; prénom : chaîne ; sexe : caractère) ;


début
si (enf = nil) ou sinon (enf^.prénom ≥ prénom) alors
insertête(enf, prénom, sexe)
sinon
insertenfant(enf^.suivant, prénom, sexe) ;
fin ;

procédure nouvellenaissance(liste : pfamille ; nomfam, prénom : chaîne ; sexe :


caractère) ;
variable
liste1 : pfamille ;
début
liste1 ← présent(liste, nomfam) ;
si liste1 ≠ nil alors
insertenfant(liste1^.enfant, prénom, sexe) ;
fin ;

8°/ Écrire une fonction booléenne qui supprime une voiture de numéro donné. La
fonction retourne la valeur vrai si et seulement si une voiture ayant ce numéro
existe et a été supprimée.

25
3 Dr Ndi Nyoungui André
Algorithmique et structures de données

Nous définissons une procédure supptêtevoit de suppression e la voiture de tête


et une procédure suppvoit de suppression d’une voiture dans la liste des voitures.

procédure suppvoituretête(var listev : pvoiture) ;


variable
p : pvoiture ;
début
p ← listev ;
listev ← listev^.suivant ;
libérer(p) ;
fin ;

fonction suppvoiture(listev : pvoiture ; numéro : chaîne) : booléen ;


début
si listev = nil alors
suppvoiture ← faux
sinon
si listev^.numéro = numéro alors
début
suppvoituretête(listev) ;
suppvoiture ← vrai ;
fin
sinon
suppvoiture ← suppvoiture(listev^.suivant, numéro) ;
fin ;

fonction supprime(liste : pfamille ; numéro : chaîne) : booléen ;


début
si (liste = nil) ou sinon suppvoiture(liste^.voiture, numéro) alors
supprime ← liste ≠ nil
sinon
supprime ← supprime(liste^.suivant, numéro) ;
fin ;

9°/ Une famille achète une voiture à une autre famille. Écrire une procédure qui
effectue le transfert de la voiture entre les deux familles.

Nous définissons une procédure de changement de propriétaire d’une voiture.

procédure changeprop(var liste1, liste2 : pvoiture ; numéro : chaîne ; var trouvé :


booléen) ;

25
4 Dr Ndi Nyoungui André
Algorithmique et structures de données

variable
p : pvoiture ;
début
si liste2 = nil alors
trouvé ← faux
sinon
si liste2^.numéro = numéro alors
début
p ← liste2^.suivant ;
liste2^.suivant ← liste1 ;
liste1 ← liste2 ;
liste2 ← p ;
trouvé ← vrai ;
fin
sinon
changeprop(liste1, liste2^.suivant, numéro, trouvé) ;
fin ;

procédure achatvoiture(liste : pfamille ; nom1, nom2, numéro : chaîne ;


var possible : booléen) ;
variable
fam1, fam2 : pfamille ;
début
fam1 ← présent(liste, nom1);
si fam1 = nil alors
possible ← faux
sinon
début
fam2 ← présent(liste, nom2) ;
si fam2 = nil alors
possible ← faux
sinon
changeprop(fam1^.voiture, fam2^.voiture, possible) ;
fin ;
fin ;

Location de voitures

Une entreprise de location de voitures a décidé d’informatiser la gestion des


locations pour un mois. Les voitures mises en location appartiennent à plusieurs
propriétaires. Les structures de données utilisées seront les suivantes :

25
5 Dr Ndi Nyoungui André
Algorithmique et structures de données

1. Un vecteur vprop dans lequel figure les noms et adresses des propriétaires de
voitures mises en location. Dans ce vecteur, chaque propriétaire apparaît une
seule fois, dans un ordre quelconque. Un entier nbprop indique le nombre de
propriétaires répertoriés. On suppose que les propriétaires ont des noms
différents.

2. Une liste chaînée, d’adresse liste, des voitures offertes en location. Chaque
voiture sera caractérisée dans la liste par :
• la marque de la voiture,
• le numéro de la voiture,
• l’indice dans le vecteur des propriétaires,
• un pointeur sur la liste des réservations (nil si aucune réservation n’est
enregistrée).

La liste [liste] des voitures est triée uniquement sur les marques de voitures.

3. Pour chaque voiture, il existe une liste chaînée des locations. Les locations ne
pouvant se faire que par jours entiers, les dates de locations sont remplacées
par des numéros de jour dans le mois. Chaque location est caractérisée par :
• le numéro du jour du début de la location,
• le numéro du jour de fin de la location (si la location est pour une seule
journée, ces numéros sont identiques),
• le nom du locataire.

Ces listes sont triées sur les dates de location. On ne peut pas avoir plus d’une
réservation pour une même voiture pour une journée donné. On suppose que les
locataires ont tous des noms différents, et qu’aucun n’a effectué plus d’une
réservation le même mois.

Les structures de données utilisées sont les suivantes :

constante
taillemax = 100 ;
type
propriétaire = article
nom : chaîne ;
adresse : chaîne ;
fin ;
vectprop = vecteur[1..taillemax] de propriétaire ;
pvoiture = ^voiture ;

25
6 Dr Ndi Nyoungui André
Algorithmique et structures de données

plocation = ^location ;
voiture = article
marque : chaîne ;
numéro : chaîne ;
indprop : entier ;
reserv : plocation ;
suivant : pvoiture ;
fin ;
location = article
jourdeb, jourfin : 1..31 ;
nomloc : chaîne ;
suivant : plocation ;
fin ;
variable
vprop : vectprop ;
nbprop : entier ;
liste : pvoiture ;

On précise que vprop, nbprop et liste sont des variables globales et peuvent donc
ne pas figurer dans les en-têtes des algorithmes.

1°/ Écrire une fonction qui retourne la position d’un propriétaire de nom donné
dans vprop. La fonction retourne zéro si aucun propriétaire de ce nom n’est
présent dans la liste.

Version itérative

fonction rangprop(nom : chaîne, vprop : vectprop ; nbprop : entier) : entier ;


variable
i : entier ;
début
i←1;
tantque (i ≤ nbprop) et alors (vprop[i].nom = nom) alors
i←i+1;
si (i ≤ nbprop) et alors (vprop[].nom = nom) alors
rangprop ← i
sinon
rangprop ← 0 ;
fin ;

Version récursive

25
7 Dr Ndi Nyoungui André
Algorithmique et structures de données

fonction rangprop(nom : chaîne, vprop : vectprop ; nbprop : entier) : entier ;


début
si nbprop = 0 alors
rangprop ← 0
sinon
si vprop[nbprop].nom = nom alors
rangprop ← nbprop
sinon
rangprop ← rangprop(nom, vprop, nbprop-1) ;
fin ;

2°/ Écrire une fonction qui délivre un pointeur sur la réservation dont le nom du
locataire est nomloc, ou bien nil si aucune réservation n’est trouvée.

On utilise une recherche associative dans une liste non triée. Ici il y a deux
niveaux de listes, la version récursive oblige donc à écrire deux fonction
séparées.

Version itérative

ponction pointeurloc(liste : pvoiture ; nom : chaîne) : plocation ;


variable
p : pvoiture ;
trouvé : booléen ;
q : plocation ;
début
p ← liste ;
trouvé ← faux ;
tantque (p ≠ nil) et non trouvé faire
début
q ← p^.reserv ;
tantque (q ≠ nil) et non trouvé faire
si q^.nomloc = nom alors
trouvé ← vrai
sinon
q ← q^.suivant ;
p ← p^.suivant ;
fin ;
si trouvé alors
pointeurloc ← q

25
8 Dr Ndi Nyoungui André
Algorithmique et structures de données

sinon
pointeurloc ← nil ;
fin ;

Version récursive

fonction cherchelocres(liste : plocation ; nom : chaîne) : plocation ;


début
si liste = nil alors
cherchelocres ← nil
sinon
si pr^.nomloc = nomloca alors
cherchelocres ← liste
sinon
cherchelocres ← cherchelocres(pr^.suivant, nom) ;
fin ;

ponction pointeurloc(liste : pvoiture ; nomloc : chaîne) : plocation ;


variable
pr : plocation ;
début
si liste = nil alors
pointeurloc ← nil
sinon
début
pr ← recherclocres(liste^.reserv, nomloc) ;
si pr ≠ nil alors
pointeurloc ← pr
sinon
pointeurloc ← pointeurloc(liste^.suivant, nomloc) ;
fin ;
fin ;

3°/ Écrire une fonction qui délivre le nombre de voitures qui appartiennent au
propriétaire de rang indice dans le vecteur vprop.

Version itérative

fonction nbvoituresprop(liste : pvoiture ; indice : entier) : entier ;


variable
liste1 : pvoiture ;

25
9 Dr Ndi Nyoungui André
Algorithmique et structures de données

compte : entier ;
début
liste1 ← liste ;
compte ← 0 ;
tantque liste1 ≠ nil faire
début
si liste1^.indprop = indice alors
compte ← compte + 1 ;
liste1 ← liste1^.suivant ;
fin ;
nbvoituresprop ← compte ;
fin ;

Version récursive

fonction nbvoituresprop(liste : pvoiture ; indice : entier) : entier ;


début
si liste nil alors
nbvoituresprop ← 0
sinon
si liste^.indprop = indice alors
nbvoituresprop ← 1 + nbvoituresprop(liste^.suivant, indice)
sinon
nbvoituresprop ← nbvoituresprop(liste^.suivant, indice) ;
fin ;

4°/ Écrire une fonction qui délivre le nombre de voitures qui appartiennent au
propriétaire de nom nomprop. La fonction retourne –1 si ce propriétaire est
inconnu.

Nous utilisons les deux fonctions définies précédemment : nbvoitures et


rangprop.

fonction nbvoitures(nomprop : chaîne ; liste : pvoitures) : entier ;


variable
indice : entier ;
début
indice ← rangprop(nomprop) ;
si indice = 0 alors
nbvoitures ← – 1
sinon

26
0 Dr Ndi Nyoungui André
Algorithmique et structures de données

nbvoitures ← nbvoituresprop(liste, indice) ;


fin ;

5°/ Écrire une fonction qui retourne le nombre total de jours de location
enregistrés dans la liste des réservations.

Il s’agit d’une extesnion de l’algorithme de calcul de la longueur d’une liste


chaînée. Au lieu d’ajouter 1 pour chaque élément, on ajoute le nombre de jours de
chaque réservation.

Shéma itératif

fonction nbjoursloc(liste : plocation) : entier ;


variable
p : plocation ;
n : entier ;
début
p ← liste ;
n←0;
tantque p ≠ nil faire
début
n ← n + p^.jourfin – p.jourdeb + 1 ;
p ← p^.suivant ;
fin ;
nbjoursloc ← n ;
fin ;

Shéma itératif

fonction nbjoursloc(liste : plocation) : entier ;


début
si liste = nil alors
nbjousrsloc ←0
sinon
nbjoursloc ← (liste^.jourfin – liste^.jourdeb + 1) +
nbjoursloc(liste^.suivant) ;
fin ;

6°/ Écrire une fonction qui retourne le nombre de voitures qui ne sont pas
louéesau cours d’un mois.

26
1 Dr Ndi Nyoungui André
Algorithmique et structures de données

C’est un nouveau calcul de nombre d’occurrences. Mais la valeur recherchée est


calculée au moyen d’un appel de la fonction nbjousloc.

Schéma itératif

fonction nbvide(liste : pvoiture) : entier ;


variable
p : pvoiture ;
nb : entier ;
début
p ← liste ;
nb ← 0 ;
tantque p ≠ nil faire
début
si nbjoursloc(p^.reserv) < alors
nb ← nb + 1 ;
p ← p^.suivant ;
fin ;
nbvide nb ;
fin ;

Version récursive

fonction nbvide(liste : pvoiture) : entier ;


début
si liste = nil alors
nbvide ← 0
sinon
nbvide ← 1 + nbvide(liste^.suivant)
sinon
nb ← nbvide(liste^.suivant
fin ;

7°/ Écrire une procédure qui imprime la liste complète des voitures, avec pour
chaque voiture, la marque, le numéro et le nom du propriétaire.

C’est le parcours simple d’une liste chaînée avec impression de chaque élément.

Schéma itératif

procédure listevoitures(liste : pvoiture) ;

26
2 Dr Ndi Nyoungui André
Algorithmique et structures de données

variable
p : liste ;
début
p ← liste ;
tantque p ≠ nil faire
début
écrite(p^.marque) ;
écrire(p^.numéro) ;
écrire(vprop[p^.indprop].nom) ;
p ← p^.suivant ;
fin ;
fin ;

Version récursive

procédure listevoitures(liste : pvoiture) ;


début
si p ≠ nil alors
début
écrite(liste^.marque) ;
écrire(liste^.numéro) ;
écrire(vprop[liste^.indprop].nom) ;
listevoitures(liste^.suivant) ;
fin ;
fin ;

8°/ Écrire une procédure qui imprime la liste des locataires pour un jour de
numéro donné numjour, avec pour chacun le nom du propriétaire ainsi que la
marque et le numéro du véhicule.

C’est un aprcours de la structure à deux niveaux de listes chaînées.


procédure listelocataires(liste : pvoiture ; numjour : entier) ;
variable
p : pvoiture ;
pr : plocation ;
trouvé : booléen ;
début
p ← liste ;
tantque p ≠ nil faire
début
pr ← p^.reserv ;

26
3 Dr Ndi Nyoungui André
Algorithmique et structures de données

trouvé ← faux ;
tantque (pr ≠ nil) et (non trouvé) faire
si pr^.jourfin < numjour alors
pr ← pr^.reserv
sinon
début
trouvé ← vrai ;
si pr^.jourdeb ≤ numjour alors
début
écrire(pr^.nomloc) ;
écrire(vprop[p^.indprop].nom)
;
écrire(p^.marque) ;
fin ;
fin ;
p ← p^.suivant ;
fin ;
fin ;

9°/ Écrire une fonction qui détermine si une voiture dont la liste de réservations
a pour adresse reserv est libre pendant le jour de numéro numjour.

Il s‘agit d’une variante, un peu plus complexe, de l’algorithme de recherche d’une


valeur dans une liste triée.

Schéma itératif

fonction libre(liste : plocation ; numjpir : entier) : booléen ;


variable
p : plocation ;
stop, trouvé : booélen ;
début
p ← liste;
stop ← faux;
trouvé ← vrai;
tantque (p ≠ nil) et (non stop) faire
si p^.jourdeb > numjour alors
stop ← vrai
sinon
si p^.semfin ≥ numjour alors
début

26
4 Dr Ndi Nyoungui André
Algorithmique et structures de données

stop ← vrai ;
trouvé ← faux ;
fin
sinon
p ← p^.suivant ;
libre ← trouvé ;
fin ;

Schéma récursif

fonction libre(liste : plocation ; numjour : entier) : booléen


début
si (liste = nil) ou sinon (liste^.jourdeb > numjour) alors
libre ← vrai
sinon
si (liste^.jourfin ≥ numjour) alors
libre ← faux
sinon
libre ← libre(liste^.suivant, numjour) ;
fin ;

10°/ Écrire une procédure qui imprime les noms et les adresses des propriétaires
de voitures d’une marque donnée qui sont libres un jour de numéro donné.

Ici encore, on recherche toutes les occurrences d’une valeur dans une liste triée.

Schéma itératif

procédure listelibre(liste : pvoiture ; marque : chaîne ; numjour : entier) ;


variable
p : pvoiture ;
stop : booléen ;
début
p ← liste ;
stop ← faux ;
tantque (p ≠ nil ) et (non stop) faire
si p^.marque < marque alors
p ← p^.suivant
sinon
si p^.marque = marque alors
début

26
5 Dr Ndi Nyoungui André
Algorithmique et structures de données

si libre(p^.reserv, numjour) alors


début
écrire(vprop[p^.indprop].nom) ;
écrire(vprop[p^.indprop].adresse) ;
fin ;
p ← p ^.suivant ;
fin
sinon
stop ← vrai ;
fin ;

Schéma récursif

procédure listelibre(liste : pvoiture ; marque : chaîne ; numjour : entier) ;


début
si liste ≠ nil alors
si p^.marque < marque alors
listelibre(liste^.suivant, marque, numjour)
sinon
si liste^.marque = marque alors
début
si libre(liste^.reserv, numjour) alors
début
écrire(vprop[liste^.indprop].nom) ;

écrire(vprop[liste^.indprop].adresse) ;
fin ;
listelibre(liste^.suivant, marque, numjou) ;
fin ;
fin ;

11°/ Écrire une procédure d’insertion d’un propriétaire de nom donné dans le
vecteur vprop. S’il y figure déjà, la procédure retourne son rang dans vprop. S’il
n’y figure pas encore, la procédure demandera son adresse, l’insérera dans vprop,
et retournera l’indice d’insertion.

Le vecteur vprop n’est pas trié, on se contente donc d’insérer les coordonnées
des nouveaux propriétaires à la fin du vecteur.

fonction insprop(nom : chaîne) : entier ;


variable

26
6 Dr Ndi Nyoungui André
Algorithmique et structures de données

i : entier ;
adresse : chaîne ;
début
i ← rangprop(nom) ;
si i = 0 alors
début
nbprop ← nbprop + 1 ;
vprop[nbprop].nom ← nom ;
écrire('Quelle est son adresse ? ') ;
lire(vprop[nbprop].adresse) ;
insprop ← nbprop ;
fin
sinon
insprop ← i ;
fin ;

12°/ Écrire une procédure qui insère en tête de liste une nouvelle voiture dont on
donne la marque, le numéro et le nom du propriétaire.

C’est l’insertion classique d’une nouvelle cellule en tête d’une liste chaînée.

procédure insvoituretête(var liste : pvoiture ; marque, numéro, nom : chaîne) ;


variable
p : pvoiture ;
début
nouveau(p) ;
p^.indprop ← insprop(nom) ;
p^.marque ← marque;
p^.numéro ← numéro ;
p^.suivant ← liste ;
p^.reserv ← nil ;
liste ← p;
fin;

13°/ Écrire une procédure qui insère en tête de liste une nouvelle voiture dont on
donne la marque, le numéro et le nom du propriétaire, après les autres voitures
de même marque. Si le nom du propriétaire est nouveau, les mises à jour
nécessaires seront effectuées.

Insertion d’un élément dans une liste triée.

26
7 Dr Ndi Nyoungui André
Algorithmique et structures de données

Schéma itératif

procédure insvoiture(var liste : pvoiture ; nom, marque, numéro : chaîne) ;


variable
p, procédent : pvoiture ;
super : booléen ;
début
si (liste = nil) ou sinon (marque < liste^.marque) alors
insvoituretête(liste, marque, numéro, nom)
sinon
début
précédent ← liste ;
p ← liste^.suivant ;
tantque (p ≠ nil) et super faire
si marque ≥ p^.marque alors
début
précédent ← p ;
p ← p^.suivant ;
fin
sinon
super ← faux ;
insvoituretête(précédent^.suivant, marque, numéro, nom) ;
fin
fin ;

Schéma récursif

procédure insvoiture(var liste : pvoiture ; nom, marque, numéro : chaîne) ;


début
si (liste = nil) ou sinon (marque < liste^.marque) alors
insvoituretête(liste, marque, numéro, nom)
sinon
insvoiture(liste^.suivant, marque, numéro, nom) ;
fin ;

14°/ Écrire une procédure qui insère une nouvelle réservation en tête d’une liste
de réservations ; le nom du locataire et les numéros des jours de début et de fin
sont donnés.

procédure instêtelocation(var liste : plocation ; nomloc : chaîne ; jour1, jour2 :


entier) ;

26
8 Dr Ndi Nyoungui André
Algorithmique et structures de données

variable
p : plocation ;
début
nouveau(p) ;
p^.suivant ← liste ;
p^.nomloc ← nomloc ;
p^.jourdeb ← jour1 ;
p^.jourfin ← jour2 ;
liste ← p ;
fin ;

15°/ Écrire une fonction qui effectue la réservation pour un locataire de nom
donné dans une liste de réservations. La fonction retourne une valeur booléenne
égale à vrai si la réservation a été possible (la période souhaitée est libre) et
faux sinon.

Il s’agit encore d’une variante de l’insertion d’un élément dans une liste triée.
Nous ne donnons que la version récursive, car la version itérative serait
particulièrement lourde.

fonction insère(var liste : plocation ; nom ; jour1, jour2 : entier) : booléen ;


début
si (liste = nil) ou sinon (liste^.jourdeb > jour2) alors
début
instêtelocation(liste, nom, jour1, jour2)
insère ← vrai ;
fin
sinon
si liste^.jourfin < jour1 alors
insère ← insère(liste^.suivant, nom, jour1, jour2)
sinon
insère ← faux ;
fin ;

16°/ Écrire une fonction qui effectue une réservation pour le locataire de nom
donné d’une voiture de marque donnée, du jour jour1 au jour jour2. La fonction
retourne une valeur booléenne égale à vrai si la réservation a été possible (il
existe une voiture de la marque souhaitée, libre les jours souhaités) et faux
sinon.

26
9 Dr Ndi Nyoungui André
Algorithmique et structures de données

On appelle ici la fonction insèrevdéfinie ci-dessus, à l’intérieur d’un algorithme


qui est semblable à la recherche d’une valeur dans une liste triée.

Schéma itératif

fonction réserver(var liste : pvoiture ; nom, marque, numéro : chaîne ;


jour1, jour2 : entier) :
booléen ;
variable
p : pvoiture ;
fintype, resok : booléen ;
début
p ← liste ;
fintype ← faux ;
resok ← faux ;
tantque (p ≠ nil) et (non resok) et (non fintype) faire
si p^.marque > marque alors
fintype ← vrai
sinon
si p^.marque < marque alors
p ← p^.suivant
sinon
si insère(p^.reserv, nom, jour1, jour2) alors
resok ← vrai
sinon
p ← p^.suivant ;
réserver ← resok ;
fin ;

Schéma récursif

fonction réserver(var liste : pvoiture ; nom, marque, numéro : chaîne ;


jour1, jour2 : entier) :
booléen ;
début
si liste = nil alors
réserver ← faux
sinon si liste^.marque > marque alors
réserver ← faux
sinon si liste^.marque < marque alors

27
0 Dr Ndi Nyoungui André
Algorithmique et structures de données

réserver ← réserver(liste^.suivant, nom, marque, numéro, jour1,


jour2)
sinon si insère(liste^.reserv, nom, jour1, jour2) alors
réserver ← vrai
sinon
réserver ← réserver(liste^.suivant, nom, marque, numéro, jour1,
jour2) ;
fin ;

17°/ Écrire une fonction qui supprime la réservation au nom de nomloc, si elle
existe, dans une liste de réservations et délivre un booléen indiquant si la
suppression a été effectué.

Il s’agit ici de la suppression d’une valeur dans une liste non triée. Nous ne
donnons que la version récursive en raison de sa simplicité.

fonction suppression(var liste : plocation ; nom : chaîne) : booléen ;


variable
p : plocation ;
début
si liste = nil alors
suppression ← faux
sinon
si liste^.nomloc = nom alors
début
p ← liste ;
liste ← liste^.suivant ;
laisser(p) ;
suppression ← vrai ;
fin
sinon
suppression ← suppression(liste^.suivant, nom) ;
fin ;

18°/ Écrire une procédure qui annule la réservation faite au nom de nomloc. S’il
n’y a pas de réservation à ce nom, la procédure imprime un message d’erreur.

Appel à la fonction précédente, dans un parcours de la liste non triée.

Version itérative

27
1 Dr Ndi Nyoungui André
Algorithmique et structures de données

procédure annuler(liste : pvoiture ; nom : chaîne) ;


variable
p : pvoiture ;
stop : booléen ;
début
p ← liste ;
stop ← faux ;
tantque (p ≠ nil) et (non stop) faire
si supression(p^.reserv, nom) alors
stop ← vrai
sinon
p ← p^.suivant ;
si p = nil alors
écrire('Erreur sur le locataire ', nom) ;
fin ;

Version récursive

procédure annuler(liste : pvoiture ; nom : chaîne) ;


début
si (liste = nil) alors
écrire('Erreur sur le locataire ', nom)
sinon
si non supression(liste^.reserv, nom) alors
annuler(liste^.suivant, nom) ;
fin ;

19°/ Écrire une procédure qui essaie de prolonger d’un jour la location au nom de
nomloc, pour la même voiture. Des messages sont affichés dans tous les cas :
prolongement possible, prolongement impossible ou réservation inexistante.

Dans cet algorithme, on commence par appeler la fonction pointeurloc pour


obtenir un pointeur sur la réservation initiale, si elle existe. Puis on regarde si le
jour qui suit le dernier jour enregistré est libre.

procédure prolonge(nom : chaîne) ;


variable
p : plocation ;
jour : entier ;
début
p ← pointeurloc(liste, nom) ;

27
2 Dr Ndi Nyoungui André
Algorithmique et structures de données

si p ≠nil alors
début
jour ← p^.jourfin + 1 ;
si p^.suivant = nil alors
début
p^.jourfin ← jour ;
écrire('Prolongation enregistrée') ;
fin
sinon
si p^.suivant^.jourdeb > jour alors
début
p^.jourfin ← jour ;
écrire('Prolongation enregistrée') ;
fin
sinon
écrire('Prolongation impossible') ;
fin
sinon
écrire('Erreur sur le locataire : ', nom) ;
fin ;

27
3 Dr Ndi Nyoungui André
Algorithmique et structures de données

Chapitre 9

Les structures dynamiques non

linéaires

Exercice 9.1
Écrire, sous forme récursive et itérative, un algorithme vérifiant qu’un arbre
binaire est ordonné.

Pour écrire cet algorithme, on utilise un parcours infixé de l’arbre et on vérifie


que les éléments ainsi énumérés sont bien ordonnés.

Version récursive

fonction ordonné(racine : pélément ; var min : télément) : booléen ;


début
si racine = nil alors
ordonné ← vrai
sinon
si ordonné(racine^.gauche, min) et alors (min racine^.donnée) alors
début
min ← racine^.donnée ;
ordonné ← ordonné(racine^.droite, min) ;
fin
sinon
ordonné ← faux ;
fin ;

A l’appel de la fonction min doit contenir un minorant de l’ensemble des valeurs


possibles de l’arbre, [racine].

Version itérative

fonction ordonné(racine : pélément ; min : télément) : booléen ;


début
trié : booléen ;

27
4 Dr Ndi Nyoungui André
Algorithmique et structures de données

rac : pélément ;
début
initpilevide ;
trié ← vrai ;
rac ← racine ;
tantque ((rac ≠ nil) ou non pilevide) et trié faire
début
tantque rac ≠ nil faire
début
empiler(rac) ;
rac ← rac^.gauche ;
fin ;
dépiler(rac) ;
trié ← min ≤ racine^.donnée ;
min ← rac^.donnée ;
rac ← rac^.droire ;
fin ;
ordonné ← trié ;
fin ;

Exercice 9.2
Transformer la fonction récursive de recherche d’un élément dans un arbre
binaire afin qu’elle délivre un pointeur sur la première occurrence de l’élément
qu’elle trouve dans l’arbre.

La fonction que nous allons écrire doit délivrer un pointeur et non un booléen ; on
ne peut donc plus l’utiliser dans un test. Nous ne pouvons pas non plus songer à
écrire :

si adresse(racine^.gauche, val) ≠ nil alors


adresse ← adresse(racine^.gauche, val)
sinon
adresse ← adresse(racine^.droite, val) ;

car cela reviendrait à appeler deux fois la même fonction récursive. Il faut donc
forcément passer par une variable auxiliaire de type POINTEUR dans laquelle on
range la valeur de adresse(racine^.gauche, val) pour pouvoir d’abord la comparer
à nil, et ensuite, s’il y a lieu, retourner cette valeur.

L’algorithme est alors le suivant :


fonction adresse(racine : pélément ; val : télément) : pélément ;
variable

27
5 Dr Ndi Nyoungui André
Algorithmique et structures de données

p : pélément ;
début
si (racine = nil) ou sinon (racine^.donnée = val) alors
adresse ← racine
sinon
début
p ← adresse(racine^.gauche, val) ;
si p ≠ nil alors
adresse ← p
sinon
adresse ← adresse(racine^.droite, val) ;
fin ;
fin ;

Exercice 9.3
Transformer la fonction itérative de recherche d’un élément dans un arbre
binaire afin qu’elle délivre un pointeur sur la première occurrence de l’élément
qu’elle trouve dans l’arbre.

Il suffit de remplacer le booléen trouvé par un pointeur adr, initialisé à nil, et le


test non trouvé par adr = nil.

L’algorithme est alors le suivant :


fonction adresse(racine : pélément ; val : télément): pélément ;
variable
rac, adr : pélément ;
début
initpilevide ;
adr ← nil ;
rac ← racine ;
tantque ((rac ≠ nil) ou non pilevide) et (adr = nil) faire
début
tantque (rac ≠ nil) et (adr = nil) faire
début
si rac^.donnée = val alors
adr ← rac ;
empiler(rac) ;
rac ← rac^.gauche ;
fin ;
dépiler(rac) ;
rac ← rac^.droite ;
fin ;

27
6 Dr Ndi Nyoungui André
Algorithmique et structures de données

adresse ← adr ;
fin ;

Exercice 9.4
Transformer la fonction récursive de recherche d’un élément dans un arbre
binaire ordonné afin qu’elle délivre un pointeur sur la première occurrence de
l’élément rencontrée.

La transformation est immédiate : il suffit de remplacer les valeurs faux et vrai,


retournées par les deux premières instructions de retour, par les valeurs nil et
racine.

L’algorithme est alors le suivant :


fonction dichotomie(racine : pélément ; val : télément): pélément ;
début
si racine = nil alors
dichotomie ← nil
sinon
si racine^.donnée = val alors
dichotomie ← racine
sinon
si racine^.donnée < val alors
dichotomie ← dichotomie(racine^.droite, val)
sinon
dichotomie ← dichotomie(racine^.gauche, val) ;
fin ;

On peut grouper les deux premières parties avec un « ou sinon », on obtient


alors :

fonction dichotomie(racine : pélément ; val : télément): pélément ;


début
si (racine = nil) ou sinon (racine^.donnée = val) alors
dichotomie ← racine
sinon
si racine^.donnée < val alors
dichotomie ← dichotomie(racine^.droite, val)
sinon
dichotomie ← dichotomie(racine^.gauche, val) ;
fin ;

Exercice 9.5

27
7 Dr Ndi Nyoungui André
Algorithmique et structures de données

Transformer la fonction itérative de recherche d’un élément dans un arbre


binaire ordonné afin qu’elle délivre un pointeur sur la première occurrence de
l’élément rencontrée.

La transformation est semblable à celle de l’exercice précédent : l’assertion de


sortie de l’itération montre que la valeur retournée après l’itération doit être
égale à rac.

L’algorithme est alors le suivant :


fonction dichotomie(racine : pélément ; val : télément) : pélément ;
variable
rac : pélément ;
début
rac ← racine ;
tantque (rac ≠ nil) et alors (rac^.donnée ≠ val) faire
si rac^.donnée < val alors
rac ← rac^.droire
sinon
rac ← rac^.gauche ;
dichotomie ← rac ;
fin ;

Exercice 9.6
Écrire une procédure qui crée un arbre binaire ordonné à partir des éléments
d’un fichier.

procédure créerarbre(nomfichier : chaîne ; var racine : pélément) ;


variable
f : fichier de télément ;
élément : télément;
début
racine ← nil ;
relire(f, nomfichier) ;
tantque non fin(f) faire
début
lire(f, élément) ;
insère(racine, élément) ;
fin ;
fermer(f) ;
fin ;

27
8 Dr Ndi Nyoungui André

Vous aimerez peut-être aussi