Algorithmique et structure de données Cours de Robert Cori – 1`ere

Algorithmique et structure de donn´ees
Cours de Robert Cori – 1`ere Ann´ee ENSEIRB
TD 2
1 Algorithmes r´ecursifs simples
1. ´
Ecrire une version r´ecursive de l’algorithme permettant de calculer rapidement
la puissance n-i`eme d’un nombre entier.
Correction 1
int puissance(int a, int n) // Version explicite
{
if (n == 1) { return a; }
else if (n % 2 == 0)
{ return puissance(a, n / 2) * puissance(a, n / 2); }
else
{ return puissance(a, n / 2) * puissance(a, n / 2) * a; }
}
int puissance(int a, int n) // Version optimis´ee
{
int p;
if (n == 1) { p = a; }
else {
p = puissance(a, n / 2);
p = p * p;
if (n % 2 == 1) { p = p * a; }
}
return p;
}
2. Sachant que le calcul du produit de deux entiers de 1000 chires prend 1/100
de seconde, calculer le temps mis pour calculer a1000000 , o`u aest un entier de
1000 chires, par cette m´ethode. Comparer ce temps `a celui que prendrait
un algorithme consistant `a eecetuer 1000000 de multiplications (noter que
log2(1000000) 20).
3. Le plus grand commun diviseur, ou PGCD, de deux entiers non nuls est le plus
grand nombre entier qui divise ces deux nombres. Par exemple, le PGCD de 1071
1
et 1029 est 21. ´
Ecrire un algorithme r´ecursif calculant le PGCD de deux entiers,
en s’inspirant de l’algorithme it´eratif donn´e en cours.
Correction 2 On consid`ere a > b. Il faut d´emontrer que tout nombre qui divise
aet bdivise aussi le reste de la division de apar b, ce qui se voit facilement
avec a = bq + r. R´eciproquement, tout nombre qui divise bet rdivise ausi a.
Donc pgcd(a, b) = pgcd(b, r).
int pgcd(int a, int b)
{
if (b == 0) { return a; }
else { return pgcd(b, a % b); }
}
2 Figure de Sierpi´nski
La figure de Sierpi´nski est une figure g´eom´etrique d’aire nulle et de p´erim`etre infini.
Elle se construit, `a partir d’un triangle ´equilat´eral, par subdivisions successives. On la
d´efinit de la fa¸con suivante :
La figure de Sierpi´nski d’ordre 1 est un triangle ´equilat´eral noir,
La figure de Sierpi´nski d’ordre nest obtenue `a partir de celle d’ordre n1 en
inscrivant un triangle ´equilat´eral blanc `a l’int´erieur de tous les triangles noirs,
formant ainsi trois nouveaux triangles noirs `a l’int´erieur de chacun de ces tri-
angles.
Voici par exemple les figures de Sierpi´nski d’ordre 1, 2, 3, 4 et 5 :
1. ´
Ecrire un algorithme r´ecursif dessinant la figure de Sierpi´nski d’ordre ndont le
sommet du sud-ouest du triangle a pour coordonn´ees (x, y) et dont la longueur
du cot´e est a:
void sierpinski(x, y, a, n)
On utilisera pour cela la fonction
tracer_ligne(x, y, a, b)
qui trace un segment entre les points de coordonn´ees (x, y) et (a, b). On remar-
quera aussi que la figure de Sierpi´nski d’ordre n > 1 est form´ee de trois figures
plus petites d’ordre n1.
2
Correction 3 Pr´eciser qu’on dessine les triangles noirs, pas les blancs !
void sierpinski(x, y, a, n)
{
if (n == 1) {
tracer_ligne( x, y, (x + a) / 2, y + a * sqrt(3) / 2);
tracer_ligne( x, y, x + a, y);
tracer_ligne(x + a, y, (x + a) / 2, y + a * sqrt(3) / 2);
}
else {
sierpinski( x, y, a / 2, n - 1);
sierpinski(x + a / 2, y, a / 2, n - 1);
sierpinski(x + a / 4, y + a * sqrt(3) / 4, a / 2, n - 1);
}
}
3 Tris
1. Le tri `a bulles consiste `a faire remonter le plus grand ´el´ement d’un tableau
jusqu’`a la fin de celui-ci (comme une bulle d’air remonte `a la surface). Pour cela,
on parcourt le tableau, en triant les ´el´ements successifs deux `a deux, autant de
fois que n´ecessaire. ´
Ecrire un algorithme eectuant le tri `a bulles.
Correction 4
void tri_a_bulles(int tab[], int taille)
{
int fin = taille - 1;
bool echange = true;
while(echange) {
echange = false;
for (i = 0; i < fin; i++) {
if (tab[i] > tab[i + 1]) {
echanger(tab[i], tab[i + 1]);
echange = true;
}
}
fin--;
}
}
2. Le tri par insertion consiste `a ins´erer successivement chaque ´el´ement dans une
partie tri´ee dont la taille augmente `a chaque ´etape. Pour ins´erer un ´el´ement on
d´ecale les ´el´ements du tableau pour ins´erer cet ´el´ement `a sa place dans la partie
d´ej`a tri´ee. ´
Ecrire un algorithme eectuant le tri par insertion.
3
Correction 5
void tri_insertion(int tab[], int taille)
{
for (i = 1; i < taille; i++) {
int m = tab[i];
int k = i;
while (k > 0 && tab[k - 1] > m) {
tab[k] = tab[k - 1];
k--;
}
tab[k] = m;
}
}
4
1 / 4 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !