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 chiffres prend 1/100
de seconde, calculer le temps mis pour calculer a1000000 , o`u aest un entier de
1000 chiffres, par cette m´ethode. Comparer ce temps `a celui que prendrait
un algorithme consistant `a effecetuer 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 n−1 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 n−1.
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 effectuant 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 effectuant 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 l'interface ou les textes ? Ou savez-vous comment améliorer l'interface utilisateur de StudyLib ? N'hésitez pas à envoyer vos suggestions. C'est très important pour nous!