Académique Documents
Professionnel Documents
Culture Documents
Structures de Données
Travaux dirigés
Ramzi Guetari
Travaux Dirigés - Algorithmique et Structures de Données
Algorithmes
itératifs
Ramzi Guetari
END-FOR
Séq-4 : FOR i ← 1 TO N DO
J ← 1
Séq-8 : FOR k ← 1 TO n DO
WHILE (J < N ) DO
i ← 1
J ← 2 * J
Opération;
END-WHILE FOR j ← 1 TO k DO
i ← 2*i
END-FOR END-FOR
FOR j ← 1 TO i DO
Séq-5 : i ← 1 Opération
END-FOR
WHILE ( i < N ) DO
END-FOR
i ← 2 * i
FOR j ← 1 TO i DO
Opération;
END-FOR
END-WHILE
SEQ-1 :
i ← n
s ← 0
WHILE (i > 0) DO
j ← 2 * i
WHILE (j > 1) DO
s ← s + (j - i) * (s + 1)
j ← j - 1
END-WHILE
i ← i div 2
END-WHILE
SEQ-2 :
P ← 1
FOR I ← 1 TO n DO
J ← 1
K ← 1
WHILE (K <= n) DO
P ← P * (K + J)
K ← K + 1
IF (K > n) THEN
J ← J + 1
IF (J <= n) THEN
K ← 1
END-IF
END-IF
END-WHILE
END-FOR
Nous supposons ici que l'ensemble considéré ne contient pas deux fois la même valeur.
Nous supposons ici que l'ensemble considéré ne contient pas deux fois la même valeur.
EXERCICE 6 : Motif 1D
Etant donnée un tableau entier A de taille N et un tableau entier F de taille U. On suppose que
U est inférieur à N.
1. Ecrire un algorithme naïf pour chercher les sous-tableaux F de A égaux au tableau F.
L’algorithme doit afficher la position début à laquelle le tableau F est trouvé.
2. Estimer sa complexité en fonction de N et U
EXERCICE 7 : Motif 2D
Exemple :
Récursivité
Ramzi Guetari
Pour convertir un nombre entier positif N de la base décimale à la base binaire, il faut opérer
par des divisions successives du nombre N par 2.
Les restes des divisions constituent la
représentation binaire. Binaire (13) 1101
1. Ecrire une fonction récursive « Binaire »
permettant d’imprimer à l’écran la
représentation binaire d’un nombre N (voir exemple en face).
2. Donner la formule récurrente exprimant sa complexité en nombre de divisions. Estimer
cette complexité.
EXERCICE 6 : Palindrome
Un mot est un palindrome si on peut le lire dans les deux sens de gauche à droite et de droite à
gauche. Exemple : KAYAK est un palindrome.
1. Ecrire une fonction récursive permettant de vérifier si un mot est ou non un palindrome.
Elle doit renvoyer 1 ou 0.
2. Estimer sa complexité en nombre d’appels récursifs en fonction de la longueur du mot.
La division de deux entiers positifs peut être réalisée à l’aide de soustraction seulement.
1. Elaborer un algorithme récursif permettant de diviser un entier a par un entier b
2. Estimer sa complexité
1 ⇔0≤n<2
un =
u n −1 + u n − 2 sinon
1. Ecrire un algorithme récursif calculant Fibonacci (n)
2. Déterminer sa complexité
3. Ecrire un algorithme récursif qui calcule, pour tout n > 0, le couple (Fibonacci (n),
Fibonacci (n -1)).
4. Utiliser l'algorithme précédent pour écrire un nouvel algorithme calculant Fibonacci (n).
5. Qu'elle est la complexité (en nombre d'additions) de cet algorithme ?
6. En utilisant un tableau pour y stocker les termes calculés, proposer un meilleur
algorithme. Estimer sa complexité au meilleur, en moyenne et au pire.
EXERCICE 10 :
1 ⇔0≤n<2
un =
2 × u n −1 + u n − 2 sinon
Soit un tableau d’entiers contenant des valeurs 0 ou bien 1. On appelle composante connexe
une suite contigüe de nombres égaux à 1. On voudrait changer la valeur de chaque
composante connexe de telle sorte que la première composante ait la valeur 2 la deuxième ait
la valeur 3, la 3ème ait la valeur 4 et ainsi de suite. Réaliser deux fonctions :
1. la première fonction n’est pas récursive et a pour rôle de chercher la position d’un 1 dans
un tableau
2. la deuxième fonction est récursive. Elle reçoit la position d’un 1 dans une séquence et
propage une valeur x à toutes les valeurs 1 de la composante connexe.
Soit une image binaire représentée dans une matrice à 2 dimensions. Les éléments m[i][j] sont
dits pixels et sont égaux soit à 0 soit à 1.
Chaque groupement de pixels égaux à 1 et
connectés entre eux forment une
composante connexe (Figure). L’objectif est
de donner une valeur différente de 1 à
chaque composante connexe (2 puis 3 puis 4
etc.).
Image binaire Image étiquetée
1. Ecrire un algorithme récursif
« propager » permettant de partir d’un point (i, j) situé à l’intérieur d’une composante
connexe et de propager une étiquette T à tous les pixels situés à l’intérieur de la
composante.
2. Estimer sa complexité.
3. Ecrire un algorithme « etiqueter » permettant d’affecter une étiquette différente à chaque
composante connexe.
EXERCICE 14 :
int x ;
foo (i + 1, j + x, k - 2)
}
CORRECTION
Exercise 14 : T (i, j, k) = O (2k+j-i )
Diviser pour
régner
Ramzi Guetari
Graphes et
Arbres
Ramzi Guetari
1. Donner une représentation du graphe ci-dessus au moyen d’une liste d’adjacence, puis au
moyen d’une matrice d’adjacence.
2. Donner une représentation du même graphe en matrices d’incidence comme celles vues
dans le cours. Quel problème se pose ici ?
3. Donner une seule matrice d’incidence représentant ce graphe, proposer pour cela une
extension de la définition vue dans le cours.
Etant donné un graphe orienté acyclique (c’est un arbre) représenté par sa matrice d’adjacence
7 6
0 1 2 3 4 5
Un graphe est un ensemble de nœuds (ou sommets) et de relations (ou arcs) entre ces nœuds.
Le graphe donné en exemple a pour nœuds: 0,1,2,3,4,5,6,7 et 8. On se propose de chercher
tous les chemins partant d’un sommet X pour arriver à un sommet Y sans passer plus d’une
fois par un même sommet.
Par exemple les chemins allant de 0 à 5 sont au 0 1 2 3 4 5 6 7 8
nombre de 4 : 0 1 2 3 4 5 , 0 1 2 8 3 4 5, 0 2 3 0 0 1 1 0 0 0 0 0 0
4 5, 0 2 8 3 4 5 1 0 0 1 0 0 0 0 0 0
Le graphe est représenté par une matrice carrée 2 0 0 0 1 0 0 0 0 0
telle que G (i, j) = 1 s’il existe un arc de i à j et 0 3 0 0 0 0 1 0 0 0 0
sinon. La matrice ci-contre représente l’exemple 4 0 0 0 0 0 1 1 0 0
de graphe ci-dessus. 5 0 0 0 0 0 0 0 0 0
6 0 0 0 0 0 0 0 1 0
S’inspirer de l’algorithme général vu en cours de 7 0 1 0 0 0 0 0 0 0
parcours d’un graphe en profondeur et écrire une 0 0 0 1 0 0 0 0 0
8
fonction en C pour trouver tous les chemins
menant d’un sommet X à un sommet Y.
Soit un graphe G orienté acyclique (ne contenant pas de cycle) composé de N sommets et
représenté par une matrice G à deux dimensions N × N, G (i, j) = 0 s’il n’existe pas d’arc
reliant i à j et si G (i, j) = 1 s’il existe un arc allant de i à j. On voudrait marquer (donner un
numéro) les sommets du graphe avec des nombres entiers positifs de telle sorte que la marque
d’un sommet soit strictement inférieure à celles de tous ses successeurs (voir exemple). Un tel
marquage est dit « topologique ».
E 7
B 3
A 1
C 5
F 6
G 2
D 9
H 8
I 4
On peut remarquer que les sommets qui n’ont pas de prédécesseurs (sommets A et G) doivent
avoir les entiers les plus petits (marque 1 et 2). Si maintenant, on ignore les sommets auxquels
on vient de donner des numéros ainsi que les arcs qui partent de ces sommets, les sommets B ,
C et I n’ont plus de prédécesseurs et doivent recevoir les marques suivantes 4, 5 et 6. Et ainsi
de suite, on répète le processus pour marquer tous les sommets. La marque des sommets sera
mise dans un tableau marque (0..N-1). Cet algorithme assez simple de marquage topologique
ne s’applique qu’à un graphe ayant plusieurs sommets sans prédécesseur. La propriété qui est
à la base de cet algorithme est la suivante : les sommets ne possédant aucun prédécesseur
doivent avoir les numéros les plus « bas » disponibles.
1. Sachant que le graphe est représenté par une matrice carrée G(0..N-1,0..N-1), et que
certains sommets ont été marqués (marque(i) > 0), écrire une fonction « start » qui
renvoie vrai si un sommet j n’a aucun prédécesseur non marqué ?
2. Ecrire une fonction « marquer » pour marquer les sommets du graphe d’une manière
topologique.
Etant donné un graphe orienté acyclique (c’est un arbre) représenté par sa matrice d’adjacence
G (G (i, j) = 1 s’il existe un arc de i à j), reprendre l’algorithme de parcours en profondeur, ci-
dessous, et le modifier pour déterminer tous les chemins menant du sommet x au sommet y.
PROCEDURE Profondeur(Graphe A)
SI A n’est pas réduit à une feuille ALORS
POUR tous les fils u de racine(A) FAIRE
Profondeur(u)
FIN-POUR
FIN-SI
FIN
Arbres Binaires
Ramzi Guetari
La hauteur d’un arbre est la plus grande profondeur que peut avoir un nœud quelconque de
l’arbre. Etant donné un arbre représenté par chaînage. Ecrire une fonction permettant de
déterminer la hauteur de l’arbre G. Proposer une solution récursive.
Etant donné un arbre binaire contenant N nœuds. Chaque nœud contient une valeur X, un
pointeur G vers le fils gauche et un pointeur D vers le fils droit. Dans cet exercice, utiliser les
définitions d’un nœud et d’un arbre données en encadré.
1. Décrire les différents types de parcours d’un arbre enraciné ?
2. Ecrire un programme (en C) pour vérifier si un arbre enraciné A est ou non un arbre
binaire de recherche. Expliquer votre méthode et préciser le type de parcours choisi.
3. Déterminer sa complexité.
On se propose d’écrire une fonction permettant de supprimer un élément dans un arbre binaire
de recherche. Pour cela, on vous demande d’écrire les fonctions suivantes :
4. search : permettant de chercher X dans un arbre A et de retourner, si X est trouvé, un
pointeur sur le nœud et un pointeur sur son père. Si l’élément est trouvé dans la racine de
l’arbre, le pointeur sur le père sera nul.
5. del_min : localise l’élément minimal d’un sous-arbre, le supprime de l’arbre et retourne
sa valeur.
6. delete_node : détruit dans un arbre A, un nœud identifié par un pointeur et un pointeur
sur son père.
7. delete : supprime une valeur X dans un arbre binaire de recherche A.
Soit un arbre binaire non vide avec : n le nombre de nœuds, f le nombre de feuilles et h sa
hauteur.
1. Quelle est la hauteur maximale d'un arbre à n nœuds ?
2. Déterminer le nombre maximal de feuilles d'un arbre de hauteur h. Indication :
commencer par déterminer une relation de récurrence donnant f.
3. Quel est le nombre maximal de nœuds d'un arbre de hauteur h ?
4. Quelle est la hauteur minimale d'un arbre de n nœuds ?
5. Montrer que le nombre de branches vides (nombre de fils gauches et de fils droits vides)
d'un arbre à n nœuds est égal à n + 1. (Indication : on distinguera les nœuds ayant zéro,
un et deux fils).
6. Montrer que le nombre de feuilles est inférieur ou égal à (n + 1) / 2 , et qu'il y a égalité si
et seulement si chaque nœud de l'arbre est soit une feuille, soit a deux fils.
7. Montrer que le nombre de feuilles d'un arbre est égal au nombre de nœuds de degré deux,
plus un.
EXERCICE 7 : Dictionnaire
Etant donné un arbre binaire de recherche A. Chaque nœud contient : val : une valeur entière,
left : un pointeur sur le fils gauche et right : un pointeur sur le fils droit. La structure
« tree » contient un seul pointeur « root » pointant sur le premier nœud de l’arbre (voir
encadré exercice 2).
1. Ecrire une fonction « int Count (tree* A) » permettant de compter et de retourner le
nombre de nœuds (non null) se trouvant dans l’arbre.
2. Ecrire une fonction « void delete (tree* A) » permettant de supprimer le nœud
contenant la plus petite valeur. Quelle est sa complexité au pire, au meilleur et moyenne ?