Vous êtes sur la page 1sur 18

Université du Sud Toulon-Var

Département d’informatique

Module I31

Algorithmique et structures de données

Exercices de travaux dirigés et de travaux pratiques

Licence d’informatique et licence de mathématiques deuxième année

Sabrina Tollari, Ouissem Ben Fredj


12 mars 2007

Table des matières


1 Tableaux 2

2 Récursivité 3

3 Références et structures 6

4 Types Abstraits de Données (T.A.D.) 9

5 Les piles 11

6 Les listes 13

7 Les arbres 15

A Questions de révision des TP 18

B Rappel sur le langage C et l’utilisation de GDB 18

Remerciement Merci à Odile Papini de m’avoir fourni les sources latex de ses TD et
TP d’Algorithmique et structures de données des années 2003-2005, à partir desquels j’ai
pu compiler ce fascicule.

res de données
2

1 Tableaux
Exercice 1.1 (TD)

On souhaite manipuler des vecteurs de n entiers. Donner le type abstrait de données


vecteur. Écrire les algorithmes des fonctions :
1. lirevecteur qui permet à l’utilisateur de saisir un vecteur v de n entiers où v est
passé en argument de la fonction.
2. affichervecteur qui permet d’afficher les composantes du vecteur v de n entiers
passé en argument de la fonction.
3. nombre qui retourne le nombre de composantes supérieures à 5 du vecteur v en
argument de la fonction.
4. rechercher qui retourne VRAI si la valeur x passée en argument de la fonction
est l’une des valeurs des composantes du vecteur v en argument de la fonction, et
retourne FAUX sinon.
5. (facultatif) maxvecteur qui retourne la plus grande des composantes du vecteur
qui est en argument de la fonction.
6. (facultatif) somme qui retourne la somme des composantes du vecteur qui est en
argument de la fonction.
7. (facultatif) somme dix qui retourne la somme des dix premières composantes du
vecteur qui est en argument de la fonction.
8. (facultatif) somme pair qui retourne la somme des composantes de rang pair du
vecteur qui est en argument de la fonction.

Exercice 1.2 (TD)

On dispose d’un tableau t de n entiers :


1. Écrire un algorithme qui détermine le plus petit élément du tableau. Combien de
comparaisons effectue l’algorithme ?
2. Écrire un algorithme qui détermine le plus petit et le plus grand élément du tableau.
Combien de comparaisons effectue l’algorithme ?
3. Pouvez-vous améliorer l’algorithme ? Aide : traiter les éléments par paire.

Exercice 1.3 (TD)

On souhaite maintenant manipuler des matrices de n entiers pour la première dimension


et de m entiers pour la deuxième dimension.
1. lirematrice qui permet à l’utilisateur de lire une matrice de n lignes et m colonnes,
qui est en argument de la fonction.
2. affichermatrice qui permet d’afficher les composantes d’une matrice de n lignes et
m colonnes, qui est en argument de la fonction.
3. (facultatif) somme qui retourne la somme des composantes d’une matrice de n
lignes et m colonnes qui est en argument de la fonction.

L2 I31 Algorithmique et structures de données


3

Exercice 1.4 (TP)

On souhaite représenter des vecteurs de TAILLE entiers où TAILLE est fixé a priori.
1. Définir en langage C la macro-constante TAILLE.
2. Écrire en langage C une définition du type abstrait de données vecteur pour
représenter les vecteurs de TAILLE entiers.
3. Écrire en langage C une déclaration d’un vecteur v de TAILLE entiers dans la
fonction main.
4. Écrire en langage C et tester les fonctions de l’exercice 1.1 en passant le tableau
comme arguments à la fonction.
5. (facultatif) Écrire la fonction int produit scalaire(vecteur x, vecteur y) qui
calcule et retourne le produit scalaire des deux vecteurs. On rappelle que le produit
scalaire de deux vecteurs X = (x1 , · · · , xTAILLE ) et Y = (y1 , · · · , yTAILLE ) est égal à
x1 .y1 + · · · + xTAILLE .yTAILLE

Exercice 1.5 (TP)

Écrire en langage C, au choix, l’un des algorithmes de tri sur les tableaux suivants (les
deux autres étant facultatifs) :
1. tri selection
2. tri insertion
3. tri bulles

Exercice 1.6 (TP)

On souhaite représenter des matrices de n lignes et de m colonnes d’entiers.


1. Écrire en langage C une définition du type abstrait de données matrice pour
représenter les matrices de n lignes et de m colonnes d’entiers.
2. Écrire en langage C une déclaration d’une matrice de n lignes et de m colonnes
d’entiers.
3. Écrire en langage C et tester les fonctions de l’exercice 1.3.

2 Récursivité
Exercice 2.1 (TD) Nombres de Fibonacci

La suite des nombres de Fibonacci est définie comme suit :



 f0 = 0
f1 = 1
fn = fn−1 + fn−2

1. Écrire l’algorithme récursif de la fonction fibrec(n : entier) : entier qui calcule


un nombre de Fibonacci.
2. Donner une table des valeurs pour n = 4.

L2 I31 Algorithmique et structures de données


4

3. Écrire l’algorithme itératif de la fonction fibit(n : entier) : entier qui calcule


un nombre de Fibonacci.
4. Écrire en C les fonctions fibit et fibrec.

Exercice 2.2 (TD) Combinaisons

Le nombre de sous-ensembles à p éléments d’un ensemble à n éléments est défini par :


 p
 Cn = 0 si p > n,
Cnp = 1 si p = 0 ou p = n,
 p p p−1
Cn = Cn−1 + Cn−1 si 0 < p < n.

1. Écrire l’algorithme récursif de la fonction combrec(n, p : entier) : entier qui


calcule le nombre de sous-ensembles à p éléments d’un ensemble à n éléments.
2. Donner une table des valeurs pour n = 4 et p = 2.
3. Écrire l’algorithme itératif de la fonction combit(n, p : entier) : entier qui calcule
le nombre de sous-ensembles à p éléments d’un ensemble à n éléments.
4. Quel est l’algorithme le plus efficace ?

Exercice 2.3 (TD) Fonction puissance

Soit le fonction puissance f (x) = xn .


1. Écrire l’algorithme récursif de la fonction prec1(x : réel, n : entier) : réel qui
calcule xn récursivement.
2. Donner une table des valeurs pour x = 2, n = 8 et x = 2, n = 11.
3. Donner le nombre de multiplications en fonction de n.
Une façon plus efficace de calculer xn est de considérer la parité de n :
– si n est pair le calcul de xn se ramène au calcul de xn/2 que l’on multiplie par lui
même,
– si n est impair n = 2r + 1, on calcule xr que l’on multiplie par lui même, puis on
multiplie le résultat par x.
1. Écrire l’algorithme récursif de la fonction prec2(x : réel, n : entier) : réel qui
calcule plus efficacement xn récursivement.
2. Donner une table des valeurs pour x = 2, n = 8 et x = 2, n = 11.
3. Donner le nombre de multiplications en fonction de n dans le pire et le meilleur des
cas.

Exercice 2.4 (TD) Tri rapide (facultatif)

Soit un tableau T [inf, sup] dont inf et sup sont respectivement, le plus petit et le plus
grand indice du tableau. Il s’agit de trier les éléments du tableau par ordre croissant. Le
tri rapide est basé sur les considérations suivantes :
– Si inf ≥ sup alors T est vide ou réduit à un seul élément, donc trié.
– Si inf < sup, soit P = T [inf ] le pivot, on commence par ranger les éléments de T
autour du pivot, c’est-à-dire à placer le pivot P en position IP de telle sorte que

L2 I31 Algorithmique et structures de données


5

– si inf ≤ i < IP alors T [i] ≤ P ,


– et si IP < i ≤ sup alors P ≤ T [i],
il suffit ensuite de trier récursivement T [inf, IP − 1] et T [IP + 1, sup].
Écrire l’algorithme récursif de tri rapide.

Exercice 2.5 (TP)

1. Écrire en langage C les deux fonctions récursives de prototype :


void afficher_croissant_rec(int tab [], int n)
void afficher_croissant_rec2(int tab [], int n, int i)
qui affichent toutes les deux le tableau tab dans l’ordre croissant de ces indices.
2. Écrire en langage C les deux fonctions récursives de prototype :
void afficher_decroissant_rec(int tab [], int n)
void afficher_decroissant_rec2(int tab [], int n, int i)
qui affichent toutes les deux le tableau tab dans l’ordre décroissant de ces indices.
3. Écrire en langage C les fonctions de l’exercice 2.3.
4. (facultatif) Écrire en langage C un programme correspondant au tri rapide vu
dans l’exercice 2.4.

Exercice 2.6 (TP) Tours de Hanoi

On dispose de n anneaux de tailles différentes et de 3 piquets, numérotés de 1 à 3 sur


lesquels les anneaux peuvent être enfilés. Au départ les n anneaux sont enfilés sur un
piquet, dans l’ordre des diamètres décroissants, le plus large en bas. Le jeu consiste à
déplacer les anneaux sur un autre piquet, rangés de la même façon qu’au départ, en
déplaçant à chaque coup un seul anneau du sommet d’une pile vers un autre piquet, en
ne posant jamais un anneau sur un autre anneau plus petit.
Exemple : pour 3 anneaux à déplacer du piquet 1 au piquet 2
déplacer l’anneau au sommet de 1 sur 2
déplacer l’anneau au sommet de 1 sur 3
déplacer l’anneau au sommet de 2 sur 3
déplacer l’anneau au sommet de 1 sur 2
déplacer l’anneau au sommet de 3 sur 1
déplacer l’anneau au sommet de 3 sur 2
déplacer l’anneau au sommet de 1 sur 2
Cet exemple est basé sur la méthode suivante :
Pour déplacer une tour de n = 0 anneaux,
il n’y a rien à faire.
Pour déplacer une tour de n anneaux du piquet 1 au piquet 2 :
il suffit de déplacer n − 1 anneaux du piquet 1 au piquet 2,
puis de déplacer l’ anneau du piquet 1 au piquet 3,
puis de déplacer la tour de n − 1 anneaux du piquet 2 au piquet 3.
Écrire l’algorithme récursif de déplacement des tours de Hanoi.

Exercice 2.7 (TP) Passer d’une base à une autre (facultatif)

L2 I31 Algorithmique et structures de données


6

1. Écrire en langage C la fonction récursive int convertirEnBase10 (int n, int


baseinit) qui convertit un nombre n ≥ 0 écrit en base baseinit en un nombre écrit
en base 10.
2. Écrire en langage C la fonction récursive int convertirEnBaseB (int n, int ba-
seB) qui convertit un nombre n ≥ 0 écrit en base 10 en un nombre écrit en base
baseB (1 < B ≤ 16).

Exercice 2.8 (TP) Calcul du pgcd (facultatif)

1. Écrire en langage C la fonction itérative int pgcd it (int a, int b) qui retourne le
plus grand commun diviseur de a et de b.
2. Écrire en langage C la fonction récursive int pgcd rec (int a, int b) qui retourne
le plus grand commun diviseur de a et de b.

3 Références et structures
Exercice 3.1 (TD)

Que valent x, y, z, t à la fin de l’algorithme suivant ?


données
x, y, z, t : entier
p, q : Ref(entier)
début
x ← 10
p ← ref(x)
y ← deref(p)
q←p
deref(p) ← 20
z ← deref(q)
t ← deref( ref(x) )
f in

Exercice 3.2 (TD)

Qu’affiche le programme en langage C ci-après ?


#include<stdio.h>
int main()
{
int a=5;
int* p;
p = &a;
printf("a=%d &a=%d p=%d *p=%d\n", a, &a, p, *p);
*p = 10;
printf("a=%d &a=%d p=%d *p=%d\n", a, &a, p, *p);
}

Exercice 3.3 (TD)

L2 I31 Algorithmique et structures de données


7

Qu’affiche le programme en langage C ci-après ? Faire le schéma de la mémoire.


#include<stdio.h>
void fonction1(int z)
{ z=4; }
void fonction2(int *p)
{ *p=5; }
int main()
{
int a=2, b=3;
fonction1(a);
fonction2(&b);
printf("a=%d b=%d\n",a,b);
}

Exercice 3.4 (TD)

1. Écrire l’algorithme d’une fonction permuter qui permet de permuter deux entiers.
Écrire ensuite cette fonction en langage C, puis écrire la fonction main qui appelle
la fonction permuter et qui affiche les deux entiers avant et après permutation.
2. Écrire l’algorithme d’une fonction mod qui remplace un entier x par le reste de
la division de x par n. Écrire ensuite cette fonction en langage C, puis écrire une
fonction main qui appelle mod et qui affiche l’entier avant et après l’appel de mod.

Exercice 3.5 (TD)

Un nombre complexe est constitué d’une partie réelle et d’une partie imaginaire.
1. Construire le type abstrait de données complexe approprié pour représenter un
nombre complexe.
2. Écrire les algorithmes des fonctions suivantes :
– creercomplexe(r : réel, i : réel) : complexe
– reelle(c : complexe) : réel
– imaginaire(c : complexe) : réel
– module(c : complexe) : réel
– affichercomplexe(c : complexe)
3. Construire le type abstrait de données approprié pour représenter la référence à
un nombre complexe et écrire l’algorithme de la fonction permutercomplexe qui
permet de permuter deux nombres complexes.
4. Écrire en langage C les définitions de types appropriés et les fonctions creercomplexe
et permutercomplexe. Pourquoi est-il nécessaire d’utiliser la fonction malloc dans
la fonction creercomplexe ?

Exercice 3.6 (TD) (facultatif)

On suppose qu’une société dispose de fiches où sont répertoriés les employés. Chaque fiche
dispose d’un numéro, d’un nom de famille, d’un prénom.
1. Construire les types abstraits de données appropriés pour représenter une fiche.

L2 I31 Algorithmique et structures de données


8

2. Écrire les algorithmes des fonctions suivantes :


– lirefiche
– afficherfiche
– affichernumero
– affichernom
3. Construire le type abstrait de données approprié pour représenter la référence à une
fiche et écrire l’algorithme de la fonction permuterfiche qui permet de permuter
deux fiches.
4. Écrire en langage C les définitions de types appropriés et les fonctions lirefiche,
afficherfiche et permuterfiche.

Exercice 3.7 (TP) Initialisation des pointeurs

1. Exécuter le programme ci-dessous. Quelle est l’erreur ?


1 #include<stdlib.h>
2 int main()
3 {
4 int *p=NULL;
5 int a=2;
6 *p=3;
7 }
2. Proposer deux solutions différentes pour réparer cette erreur (pour chaque solution,
il suffit de rajouter une instruction entre les lignes 5 et 6 du programme).
– Solution utilisant la variable a :
– Solution utilisant une allocation dynamique :
3. Pourquoi est-il préférable d’initialiser les pointeurs à NULL ?

Exercice 3.8 (TP) Allocation dynamique des tableaux

Écrire en langage C un programme qui :


1. déclare et alloue dynamiquement un tableau t de 3 entiers,
2. affiche la valeur de la variable t et l’adresse de t[0]. Conclusion ?
3. saisie et affiche les éléments du tableau avec la notation “pointeur” (sans utiliser les
crochets),
4. affiche les octets du tableau t, octet par octet (et non pas par groupe de 4 oc-
tets). Pour cela, utiliser une variable p de type char * initialisée avec la valeur
de la variable t (rappel : l’opérateur de conversion de type a la syntaxe suivante :
(type) expression. Par exemple, la valeur de (float) 3 est le flottant 3.0 et la
valeur de (int)12.453 est l’entier 12). Saississez dans le tableau les valeurs 127,
128 et 258. D’après l’affichage, comment sont stockés les entiers dans un int ?

Exercice 3.9 (TP) Allocation dynamique des matrices

1. Déclarer et allouer dynamiquement une matrice de n lignes et m colonnes.


2. (facultatif) Écrire en langage C les fonctions qui permettent de saisir et afficher
une matrice avec les notations “pointeurs” (sans utiliser les crochets).

L2 I31 Algorithmique et structures de données


9

3. (facultatif) Écrire en langage C la fonction somme mat qui retourne la matrice


de n entiers pour la première dimension et de m entiers pour la deuxième dimension
qui est la somme de deux matrices passées en argument à la fonction.

Exercice 3.10 (TP)

Écrire en langage C et tester les fonctions des exercices 3.4 et 3.5.

Exercice 3.11 (TP) Vecteurs de nombres complexes

1. Définir en langage C le type vcomplexe approprié pour représenter des vecteurs


de nombres complexes.
2. Écrire les fonctions :
(a) saisirvecteur qui saisit un vecteur de nombres complexes.
(b) affichervecteur qui affiche un vecteur de nombres complexes.
(c) somme (facultatif) qui effectue la somme de deux vecteurs de nombres com-
plexes.

Exercice 3.12 (TP) Crible d’Erastothène (facultatif)

Il s’agit de déterminer tous les nombres premiers inférieurs à une valeur donnée N par
la méthode du crible d’Erastothène. La méthode consiste à dresser une liste des nombres
considérés de 1 à N et à y rayer les nombres multiples d’entiers.
1. Donner l’algorithme de la fonction crible.
2. Donner une première version en C de la fonction crible statique, c’est-à-dire dans le
cas où le nombre maximal N est connu et constant (allocation statique).
3. Donner une deuxième version en C de la fonction crible dynamique, c’est-à-dire
dans le cas où le nombre maximal N n’est pas constant et est fourni en argument à
fonction (allocation dynamique).

4 Types Abstraits de Données (T.A.D.)


Exercice 4.1 (TD) Le T.A.D. poly

Soit le T.A.D. défini en cours pour représenter les polynômes à coefficients entiers.
Donner le nom poly à Structure(deg : entier, coef : Tableau(MAXDEG,entier)).
1. Écrire les algorithmes pour les fonctions de manipulation des polynômes suivantes :
(a) lirepoly() : poly qui permet de saisir le degré du polynôme ainsi que ses
coefficients.
(b) afficherpoly(p : poly) qui permet d’afficher le polynôme.
(c) coef(p : poly, j : entier) : entier qui retourne le coefficient correspondant
à l’exposant j spécifié comme argument.
(d) insere(p : poly, c : entier, j : entier) : poly qui permet d’insérer un terme
d’exposant j et de coefficient c spécifiés comme arguments.

L2 I31 Algorithmique et structures de données


10

(e) supprime(p : poly, j : entier) : poly qui permet de supprimer du polynôme


p le terme d’exposant j.
(f) somme (p : poly, q : poly) : poly qui retourne le polynôme somme des
deux polynômes spécifiés comme arguments.
2. Évaluer un polynôme consiste à calculer la valeur du polynôme pour une valeur de x
donné. Par exemple, si P (x) = x3 + 3x2 + 1 et x = 2 alors P (2) = 23 + 3 ∗ 22 + 1 = 21.
La méthode de Horner permet d’évaluer un polynôme sans calculer de puissances :
l’idée consiste à réécrire le polynôme en utilisant des parenthèses emboı̂tées, ainsi
P (x) = x3 + 3x2 + 1 devient P (x) = (((1)x + 3)x + 0)x + 1.
Écrire les algorithmes des fonctions :
(a) evaluerpoly qui utilise la fonction prec2 définie dans l’exercice 2.3.
(b) evaluerpolyrec qui utilise la méthode de Horner.

Exercice 4.2 (TD) Le T.A.D. string

Soit le type abstrait de données string défini en cours pour représenter les chaı̂nes de
caractères.
Donner le nom string à Ref(caractère).
Écrire les algorithmes pour les fonctions de manipulation des chaı̂nes de caractères
suivantes :
1. lirechaine() : string qui permet de saisir une chaı̂ne de caractères.
2. chainevide() : string qui retourne la chaı̂ne vide.
3. est vide(s : string) : booléen qui indique si la chaı̂ne spécifiée comme argument
est vide ou pas.
4. longueur(s : string) : entier qui retourne la longueur de la chaı̂ne de caractères
spécifiée comme argument.
5. concat(s1 : string, s2 : string) : string qui retourne une chaı̂ne de caractères
dont les éléments sont ceux de la première chaı̂ne de caractères suivis de ceux de la
deuxième chaı̂ne de caractères.
6. (facultatif) substr(s : string, p1 : entier, p2 : entier) : string qui retourne
la sous chaı̂ne de caractères contenant les caractères de la chaı̂ne s, de la position
p1 à la position p2. Par exemple, substr(”Bonjour”,3,6) retourne ”jour”.

Exercice 4.3 (TD) (facultatif) Représentation avec tableaux de caractères et représentation


avec références des chaı̂nes de caractères

1. Écrire la fonction afficherchaine qui permet d’afficher la chaı̂ne de caractères qui


est en argument, en fonction des types et des représentations suivants :
(a) Donner le nom string au type Tableau(n,caractère) et utiliser la représentation
avec tableaux de caractères.
(b) Donner le nom string au type Ref(caractère) et utiliser la représentation avec
références.
2. Écrire en langage C les définitions de types appropriés et les 2 versions de l’algo-
rithme.

L2 I31 Algorithmique et structures de données


11

Exercice 4.4 (TP) Les arguments de la fonction main.

La fonction main peut prendre deux paramètres. Son prototype devient :


int main(int argc, char * argv[]).
Le premier argument argc contient le nombre d’éléments de la ligne de commande. Le
deuxième argument argv contient la liste des éléments.
1. Écrire une fonction main qui affiche : le nom du programme, le nombre d’arguments
et la liste des arguments de la ligne de commande. Exemple :
deug11:~I31/TP4>gcc tp4exo1.c -o tp4exo1
deug11:~I31/TP4>./tp4exo1 hello world
Nom du programme : ./tp4exo1
Nombre d’arguments : 3
Liste des arguments : ./tp4exo1 hello world
2. Faire un schéma de la mémoire correspondant à la variable argv pour la ligne de
commande : ./tp4exo1 hello world.
3. (facultatif) Écrire un programme qui fait l’opération indiquée en ligne de com-
mande et qui affiche le résultat (vous aurez besoin de la fonction atoi). Par exemple,
pour la ligne de commande : ./tp4exo1b 2 + 3, le programme affiche : Somme=5.

Exercice 4.5 (TP)

1. Définir en langage C la macro-constante MAXDEG qui indique le degré maximal


du polynôme. Pourquoi est-on obligé de définir un degré maximal ?
2. Écrire en langage C les définitions de types appropriés et les fonctions de manipu-
lation des polynômes de l’exercice 4.1.
3. (facultatif) Ecrire en langage C la fonction : poly mult(p1 : poly, p2 : poly) qui
retourne le polynôme produit des polynomes p1 et p2.
4. Écrire une fonction main qui permet d’utiliser ces fonctions. (facultatif) En par-
ticulier calculer la somme et le produit des polynômes : p1 (x) = 3 x5 + 2 x3 + 1 et
p2 (x) = 6 x5 − 5 x4 − 2 x3 + 8 x2 . Évaluer les polynômes p1 (x) et p2 (x) en −2.

Exercice 4.6 (TP) (facultatif)

Écrire en langage C les fonctions des exercices 4.2 et 4.3.

5 Les piles
Exercice 5.1 (TD) Représentation séquentielle

Soit la représentation séquentielle pour le type abstrait de données pile défini en cours
pour une pile d’entiers :
Donner le nom pile à Structure(sommet : entier, s : Tableau(n, entier))
Donner le nom ppile à Ref(pile)
Écrire les algorithmes pour les fonctions de manipulation de la pile suivantes :

L2 I31 Algorithmique et structures de données


12

1. creer pile() : pile qui renvoie une pile initialisée avec une pile vide.
2. pile vide(p : pile) : booléen qui indique si la pile spécifiée en argument est vide
ou pas.
3. sommet pile(p : pile) : entier qui retourne le sommet de la pile spécifiée en
argument.
4. empiler(x : entier, ptr : ppile) qui permet d’empiler un élément spécifié comme
argument dans la pile référencée par la référence spécifiée comme argument.
5. depiler(ptr : ppile) : entier qui permet de dépiler la pile référencée par la référence
spécifiée comme argument et de retourner l’élément dépilé.
6. afficherpile(ptr : ppile) qui permet de parcourir la pile référencée par la référence
spécifiée comme argument et d’afficher les éléments de la pile.

Exercice 5.2 (TD) Représentation chaı̂née

Soit maintenant, la représentation chaı̂née pour le type abstrait de données pile défini en
cours :
Donner le nom element à Structure(cour : entier, suiv : pelement)
Donner le nom pelement à Ref(element)
Donner le nom pile à Ref(element)
Donner le nom ppile à Ref(pile)
Écrire les algorithmes pour les fonctions de manipulation de la pile suivantes :
1. creer pile() : ppile qui permet de créer une pile référencée par la référence spécifiée
comme argument en l’initialisant avec une pile vide.
2. pile vide(ptr : ppile) : booléen qui indique si la pile référencée par la référence
spécifiée en argument est vide ou pas.
3. empiler(x : entier, ptr : ppile) qui permet d’empiler un élément spécifié comme
argument dans la pile référencée par la référence spécifiée comme argument.
4. depiler(ptr : ppile) : entier qui permet de dépiler la pile référencée par la référence
spécifiée comme argument et de retourner l’élément dépilé.
5. afficherpile(ptr : ppile) qui permet de parcourir la pile référencée par la référence
spécifiée comme argument et d’afficher les éléments de la pile.

Exercice 5.3 (TP) (facultatif)

1. Écrire en langage C les fonctions de manipulation de la pile en représentation


séquentielle. On considérera une pile d’entiers. Écrire une fonction main qui per-
met d’utiliser ces fonctions.
2. Écrire en langage C les fonctions de manipulation de la pile en représentation
chaı̂née. On considérera une pile de réels. Écrire une fonction main qui permet
d’utiliser ces fonctions.

L2 I31 Algorithmique et structures de données


13

6 Les listes
Exercice 6.1 (TD)

Soit la représentation chaı̂née pour le type abstrait de données liste défini en cours pour
une liste d’entiers :
Donner le nom element à Structure(el : entier, suiv : pelement)
Donner le nom pelement à Ref(element)
Donner le nom liste à Ref(element)
Donner le nom pliste à Ref(liste)
Écrire les algorithmes pour les fonctions de manipulation de liste suivantes :
1. compter rec(ptrl : pliste) : entier qui compte récursivement le nombre d’entiers
contenus dans la liste.
2. compter it(ptrl : pliste) : entier qui compte itérativement le nombre d’entiers
contenus dans la liste.
3. appartient(x : entier, ptrl : pliste) : booléen qui renvoie un booléen qui indique
si l’entier passé en argument appartient à la liste référencée par la référence spécifiée
comme argument.
4. prem position(x : entier, ptrl : pliste) : pelement qui renvoie la position
(référence) de la première occurrence (par rapport au début de liste) de l’entier passé
en argument dans la liste référencée par la référence spécifiée comme argument.
5. (facultatif) prem rang(x : entier, ptrl : pliste) : entier qui renvoie la position
(rang) de la première occurrence (par rapport au début de liste) de l’entier passé en
argument dans la liste référencée par la référence spécifiée comme argument.
6. list position(x : entier, ptrl : pliste) : pliste qui renvoie une référence à une
nouvelle liste contenant les positions (rang) des occurrences de l’entier passé en
argument dans la liste référencée par la référence spécifiée comme argument.
7. (facultatif) concatener(ptrl1 : pliste, ptrl2 : pliste) qui permet de concaténer
une liste référencée par la référence spécifiée comme premier argument avec la liste
référencée par la référence spécifiée comme deuxième argument.
8. (facultatif) trier(ptrl : pliste) qui permet de trier récursivement la liste référencée
par la référence spécifiée comme argument.

Exercice 6.2 (TD)

Soit maintenant, la représentation chaı̂née pour le type abstrait de données polynôme :


un polynôme est considéré comme une liste chaı̂née de monômes. Écrire les algorithmes
pour les fonctions de manipulation des polynômes suivantes :
1. Écrire la définition des types abstraits de données pour la représentation chaı̂née
des polynômes.
2. creer poly qui permet de créer un polynôme.
3. inserer croissant qui permet d’insérer un monôme spécifié comme argument, par
ordre croissant des exposants, dans la liste constituée par le polynôme.

L2 I31 Algorithmique et structures de données


14

4. afficher poly rec qui permet de parcourir récursivement le polynôme et de l’affi-


cher.
5. reduire poly qui permet de simplifier un polynôme de telle sorte que tous les
monômes de coefficient non nuls, du polynôme spécifié comme argument, aient des
degrés différents.
6. evaluer poly rec qui retourne l’évaluation du polynôme pour une valeur spécifiée
comme argument de manière récursive.
7. (facultatif) evaluer poly it qui retourne l’évaluation du polynôme pour une va-
leur spécifiée en argument de manière itérative.
8. supprimer poly qui permet de détruire le polynôme.
9. somme poly qui calcule le polynôme somme des deux polynômes.
10. (facultatif) produit poly qui calcule le polynôme produit des deux polynômes.

Exercice 6.3 (TP)

Soit la représentation chaı̂née pour le type abstrait de données liste défini en cours
pour une liste d’entiers :
1. Écrire en langage C les définitions de types nécessaires à l’implantation d’une liste
chaı̂née pour représenter une liste d’entiers.
2. Écrire en langage C les fonctions de manipulation de listes suivantes :
(a) creer liste() : pliste qui permet de créer une liste et de l’initialiser avec une
liste vide.
(b) booléen liste vide(ptr : pliste) qui indique si la liste pointée par le pointeur
spécifié comme argument, est vide ou pas.
(c) inserer en tete(ptr : pliste, px : pelement) qui permet d’insérer px en
tête de la liste pointée par ptr.
(d) inserer apres (ptr : pliste, px : pelement, py : pelement) qui permet
d’insérer px après py dans la liste pointée par ptr.
(e) inserer en fin(ptr : pliste, px :pelement) qui permet d’insérer px en fin
de la liste pointée par ptr.
(f) extraire en tete(ptr : pliste) : pelement qui permet d’extraire un élément
en tête de la liste pointée par ptr.
(g) extraire apres(ptr : pliste, py : pelement) : pelement qui permet d’ex-
traire un élément situé après un élément py dans la liste pointée par ptr.
(h) extraire en fin(ptr : pliste) : pelement qui permet d’extraire un élément
en fin de la liste pointée par ptr.
(i) afficher it liste(ptr : pliste) qui permet de parcourir itérativement la liste
et d’afficher les éléments de la liste pointée par ptr.
(j) afficher rec liste(ptr : pliste) qui permet de parcourir récursivement la liste
et d’afficher les éléments de la liste pointée par ptr.
(k) detruire liste(ptr : pliste) qui permet de détruire une liste pointée par ptr.

L2 I31 Algorithmique et structures de données


15

3. (facultatif) Écrire en langage C les fonctions de manipulation de listes en représentation


chaı̂née des entiers de l’exercice 6.1.

Exercice 6.4 (TP) Liste doublement chaı̂née (facultatif)

En utilisant la représentation doublement chaı̂née pour le type abstrait de données liste,


écrire en langage C les fonctions de manipulation de polynômes en représentation chaı̂née,
ainsi qu’une fonction main qui permet d’utiliser ces fonctions. En particulier, calculer la
somme et le produit des polynômes : p1 (x) = −6 x50 − 2 x8 + 1 et p2 (x) = 6 x50 − 5 x13 −
2 x8 + 8 x. Évaluer les polynômes p1 (x) et p2 (x) en −2.

7 Les arbres
Exercice 7.1 (TD) Parcours d’arbres

Soit un arbre binaire représentant une généalogie dont les noeuds sont étiquetés par
des lettres numérotées :
étiquette pére mère
A B1 B2
B1 C1 C2
B2 C3 C4
C1 D1 D2
C2 D3 D4
C3 D5 D6
C4 D7 D8
Quel sera le résultat de l’affichage si le parcours de l’arbre est effectué de façon :
1. préfixée ?
2. infixée ?
3. postfixée ?

Exercice 7.2 (TD) Généalogie

Soit les types abstraits de données suivants :


Donner le nom chaine à Tableau(n, caractère)
Donner le nom personne à
Structure(nom : chaine, prenom : chaine, pere : ppersonne, mere : ppersonne)
Donner le nom ppersonne à Ref(personne)

Écrire les algorithmes pour les fonctions de manipulation des personnes suivantes :
1. nobody() : ppersonne qui permet d’initialiser un objet de type ppersonne avec
les champs nom et prénom initialisés avec une chaı̂ne vide et les champs père et
mère initialisés avec NULL.
2. creer personne() : ppersonne qui permet de remplir intéractivement les champs
de la personne, ainsi que ces ancêtres et qui renvoie un objet de type ppersonne.

L2 I31 Algorithmique et structures de données


16

3. identite(ppersonne) qui permet d’afficher l’identité (nom et prénom) d’une per-


sonne spécifiée en argument.
4. identite pere(ppersonne) qui permet d’afficher l’identité (nom et prénom) du
père d’une personne spécifiée en argument.
5. (facultatif) identite mere(ppersonne) qui permet d’afficher l’identité (nom et
prénom) de la mère d’une personne spécifiée en argument.
6. identite aieul it(ppersonne) qui permet de trouver itérativement et d’afficher
l’identité (nom et prénom) du plus vieil ancêtre (branches des pères uniquement)
connu d’une personne spécifiée en argument.
7. identite aieule rec(ppersonne) qui permet de trouver récursivement et d’afficher
l’identité (nom et prénom) de la plus vielle ancêtre (branches des mères uniquement)
connue d’une personne spécifiée en argument.
8. a prefixe(ppersonne) qui parcours l’arbre de façon préfixée et affiche l’identité
des personnes correspondant aux noeuds rencontrés.
9. a infixe(ppersonne) qui parcours l’arbre de façon infixée et affiche l’identité des
personnes correspondant aux noeuds rencontrés.
10. a postfixe(ppersonne) qui parcours l’arbre de façon postfixée et affiche l’identité
des personnes correspondant aux noeuds rencontrés.
11. (facultatif) grand parent(ppersonne) qui affiche l’identité des grands-parents
de la généalogie.
12. (facultatif) aieul(ppersonne) qui affiche l’identité des personnes les plus âgées
de la généalogie.

Exercice 7.3 (TD) Expressions arithmétiques

Pour manipuler et évaluer des expressions arithmétiques, on utilise une structure d’arbre.
Les noeuds de l’arbre sont étiquetés par des entiers et des opérateurs arithmétiques, par
exemple, +, -, *.
1. Écrire la définition des types utilisés pour les expressions arithmétiques.
2. Écrire les algorithmes des fonctions de manipulation d’expressions arithmétiques :
– creer noeud qui crée un noeud de l’arbre.
– creer feuille qui crée une feuille de l’arbre.
– creer arbre qui crée un arbre.
– exp prefixe qui affiche l’expression de façon préfixée.
– exp infixe qui affiche l’expression de façon infixée.
– exp postfixe qui affiche l’expression de façon postfixée.
– rechercher noeud qui recherche le noeud de l’arbre qui contient l’opérateur
arithmétique en paramètre.
– evaluation qui évalue l’expression et affiche le résultat de l’évaluation.
– m a j expression qui met à jour une expression déjà existante en construisant
une nouvelle expression à partir de l’ancienne, d’un opérateur et d’un opérande
saisis au clavier.
– detruire expression qui détruit une expression.

L2 I31 Algorithmique et structures de données


17

Exercice 7.4 (TP)

Écrire en langage C les fonctions de manipulation des expressions arithmétiques de l’exer-


cice 7.3 ainsi qu’une fonction main comportant un menu permettant l’utilisation (convi-
viale pour l’utilisateur) des fonctions de manipulation des expressions arithmétiques. Les
affichages de l’arbre pourront se faire avec une indentation.

Exercice 7.5 (TP) (facultatif)

Écrire en langage C les fonctions de parcours de la généalogie de l’exercice 7.2 ainsi qu’une
fonction main qui permet d’utiliser ces fonctions.

Exercice 7.6 (TP) Arbre de questions (facultatif)

Soit un arbre binaire de questions, contenant pour chaque noeud, un pointeur vers le
texte correspondant à la question à poser, un pointeur vers le sous-arbre gauche des ques-
tions, un pointeur vers le sous-arbre droit des questions. Les questions sont booléennes,
on peut répondre par oui ou par non.
Par exemple, soit un arbre binaire dont les noeuds sont étiquetés comme suit :

étiquette f ils gauche f ils droit


homme belge animal
belge T intin Corto Maltese
animal vertébré
vertébré mammif ére insecte
mammif ére tigre oiseau
insecte mouche

1. Écrire en langage C une fonction poser questions qui permet de poser les ques-
tions d’une branche de l’arbre en fonction des réponses ( O (oui) et N (non)) de
l’utilisateur. Par exemple :
Est-ce un homme ? O
Est-ce un belge ? N
Est-ce Corto Maltese ? O
Fin des questions : vous avez gagné ! ! ! !
2. Écrire une fonction lister questions qui permet de lister de manière indentée les
questions de l’arbre.
3. Écrire une fonction inserer questions qui permet d’insérer une question à réponse
booléenne dans l’arbre. La nouvelle question est insérée au niveau d’une feuille après
avoir répondu aux questions qui mènent à cette feuille.
4. Écrire une fonction détruire arbre qui détruit l’arbre.
5. Écrire une fonction main comportant un menu permettant l’utilisation (conviviale
pour l’utilisateur) des fonctions de manipulation de l’arbre de questions.

L2 I31 Algorithmique et structures de données


18

A Questions de révision des TP


Vous trouverez dans cette section des questions qui vous permettront de vérifier si
vous avez bien compris certaines difficultées des TP.
1. Quelle est la différence entre la directive #define T1 5 et l’instruction int T2=5; ?
2. Quelle est la différence entre une variable locale et une variable globale ?
3. Pourquoi ne faut-il jamais retourner l’adresse d’une variable locale à une fonction ?
4. Quelle est la différence entre une fonction récursive et une fonction itérative ?
5. Pourquoi faut-il utiliser la fonction atoi dans la question 3 de l’exercice 4.4 ?
6. Que faut-il rajouter à un programme C pour utiliser la fonction pow ?
7. Quels sont les avantages d’une allocation dynamique sur une allocation statique ?
8. Lorsqu’on alloue la mémoire pour une chaı̂ne de caractères de longueur n, combien
d’octets faut-il réserver ?
9. Que doit-on faire pour chaque variable allouée dynamiquement lorsque l’on n’en a
plus l’utilité ?

B Rappel sur le langage C et l’utilisation de GDB


La commande pour compiler un programme est :
deug10:~> gcc fichier.c [-o nomdelexecutable] [-g] [-Wall] [-lm]
Les options les plus courantes sont notées entre crochets. A quoi servent chacune de ces
options ?
Pour détecter certaines erreurs de programmation, on peut utiliser un débogueur, tel que
gdb. Pour utiliser gdb, compiler votre programme C avec l’option -g.
deug10:~> gdb nomdelexecutable
(gdb) break numero_ligne_prog_C
(gdb) run
(gdb) display nom_variable
(gdb) c
(gdb) bt
(gdb) quit
break permet d’indiquer un point d’arrêt à la ligne indiquée en argument. run lance
l’exécution du programme. Cette exécution s’interrompt lorsque l’exécution arrive à un
point d’arrêt ou bien que le programme renvoie un message d’erreur, tel qu’une erreur de
segmentation. On peut alors visualiser les variables avec la commande display ou visua-
liser la pile des appels de fonctions avec bt (backtrace). On peut poursuivre le programme
avec la commande c. Pour plus de détails (man gdb ou commande help).

Références
[1] M. Divay. Algorithmes et structures de données génériques. Dunod, 2004.
[2] J.P. Braquelaire. Méthodologie de la programmation en C. Dunod, 2000.
[3] T. Cormen, C. Leiserson et R. Rivest. Introduction à l’algorithmique. Dunod, 1994.

L2 I31 Algorithmique et structures de données

Vous aimerez peut-être aussi