Académique Documents
Professionnel Documents
Culture Documents
Correction TD in 301
Correction TD in 301
Philippe Gambette
1 3
3 3 3 3 5 5 5 5 5 5 7
Sance 2 (12/10/2007) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Preuve d'arrt de l'algorithme 6 Preuve d'arrt de l'algorithme 7 Preuve d'arrt de l'algorithme 8
2 Invariants
2.1 Sance 4 (19/10/2007) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.1 2.1.2 2.2 2.2.1 2.2.2 2.2.3 2.3 2.3.1 2.3.2 2.3.3 Arrt et invariants de l'algorithme 15 Arrt et invariants de l'algorithme 13 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
8 8 9 10 10 10 11 11 11 12 13
Sance 5 (24/10/2007) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invariant et correction de l'algorithme 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . Invariant et correction de l'algorithme 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . Correction de l'algorithme 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Correction de l'algorithme de recherche squentielle en tableau tri . . . . . . . . . . . . Correction de l'algorithme de multiplication par additions successives . . . . . . . . . . Invariant de l'algorithme de recherche dichotomique modi . . . . . . . . . . . . . . . .
Sance 6 (26/10/2007) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3 Complexit
3.1 Sance 6 (26/10/2007) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.1 Complexit de l'algorithme 14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
14 14
4 Listes chanes
4.1 4.2 Sance 9 (14/11/2007) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.1 4.2.1 4.2.2 4.2.3 4.2.4 4.3 4.3.1 4.3.2 4.3.3 4.3.4 4.4 4.4.1 4.4.2 Familiarisation avec les listes chanes Algorithmes sur les listes chanes . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sance 10 (28/11/2007) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
15 15 16 16 16 17 17 17 17 19 19 19 20 20 20
Adresse de la dernire cellule d'une liste . . . . . . . . . . . . . . . . . . . . . . . . . . . Premier lment mis la n d'une liste Suppression de tous les lments de valeur donne d'une liste
Sance 11 (07/12/2007)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Suppression de tous les doublons d'une liste . . . . . . . . . . . . . . . . . . . . . . . . . Miroir d'une liste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Concatnation de deux listes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Familiarisation avec les listes doublement chanes Miroir d'une liste doublement chane
5 Arbres
5.1 Sance 12 (12/12/2007) 5.1.1 5.1.2 5.1.3 5.2 5.2.1 5.2.2 5.2.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Familiarisation avec les arbres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Hauteur d'un arbre binaire Nombre de feuilles d'un arbre binaire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Intermde complexit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
22 22 22 22 23 23 23 23
Nombre de nuds de profondeur xe d'un arbre binaire Eeuillage d'un arbre binaire
25
25 25 25 26 26
Avertissement
Ce document contient ventuellement des erreurs volontaires, que j'ai indiques pendant les sances de TD. Je signale aussi que la pratique de recherche des exercices pendant la sance de TD est indispensable pour s'entraner, et dconseille cordialement l'utilisation exclusive de ce corrig (la veille de l'examen par exemple) sans avoir assist aux sances. Signalez-moi toute erreur involontaire longera) : Cindy Sartre Les cours d'algorithmique de L1 sont disponibles l'adresse
gambette@lirmm.fr.
A Les indications sur l'utilisation du langage L T X pour que vous puissiez participer la rdaction de ce corrig est E disponible avec le chier source de ce document l'adresse http://www.lirmm.fr/~gambette/EnsAlgo.php.
http://www.lirmm.fr/~vilarem/FLIN101/.
Chapitre 1
Rvisions, preuves d'arrt
1.1
Sance 1 (10/10/2007)
1.1.1 Algorithme 1
Donnes : T [1..n] tableau d'entiers, x un entier. Rsultat : P P est un des lments de T les plus proches de x, c'est dire P P dbut
|x P P | |x T [i]|. T
et
i 1, n
n
P P T [1];
T [i];
: entier)
1.1.2 Algorithme 2
En considrant que
Donnes : A[1..n] et B[1..n] deux tableaux de n entiers et Som un entier. Rsultat : Renvoie Vrai s'il existe i, j [1..n] tels que A[i] + B[j] = Som, renvoie Faux sinon. dbut pour tous les i de 1 n faire pour tous les j de 1 n faire si A[i] + B[j] = Som alors renvoyer Vrai; n n renvoyer Faux; n Algorithme 2 : Somme?(d A[1..n] : tableau d'entiers, d B[1..n] : tableau d'entiers, d Som : entier)
boolen Alternative "tordue" qui vite la cassure du
1.1.3 Algorithme 4
T [1..n, 1..n]
Pour la culture. . .
T [i, j]
et la colonne
j.
O(n3 ).
On peut en obtenir un en
Donnes : A[1..n] et B[1..n] deux tableaux de n entiers et Som un entier. Rsultat : Renvoie Vrai s'il existe i, j 1, n tels que A[i] + B[j] = Som, renvoie Faux sinon. dbut
i 1; j 1; tant que j < n + 1 et A[i] + B[j] = Som si i = n alors j j + 1; i 0;
faire
sinon n
i i + 1;
n Algorithme 3
boolen
A[1..n]
: tableau d'entiers,
B[1..n]
: tableau d'entiers,
Som
: entier) :
Donnes : T [1..n, 1..n] un tableau de 0 et de 1. Rsultat : Renvoie Vrai si et seulement si T possde deux lignes identiques, c'est dire ssi dbut pour tous les i de 1 n faire pour tous les j de 1 n faire
k 1; i = j 1, n / k 1, n
,
n
n
du tableau en
O(n2 log n)
O(n)),
tableau pour vrier si elle est gale la suivante. On peut mme tre encore plus astucieux en utilisant le fait que le tableau contient seulement des 0 et des 1 et en commenant par le trier par un tri par base (tri radix), avant de comparer chaque ligne avec la suivante, pour obtenir une complexit totale en
O(n2 ).
1.2
Sance 2 (12/10/2007)
1.2.1 Algorithme 5
On n'utilise qu'un seul tableau
n + 1.
Donnes : T [1..n, 1..n] un tableau de 0 et de 1. Rsultat : T modi de telle sorte que e soit insr la bonne place parmi les m premiers lments (le dbut n
tableau
T [1..m + 1]
i 1;
/* la i-ime case et celles sa droite doivent tre dcales d'une case droite pour pouvoir insrer e en i-ime position. */ j n; tant que j i faire T [j + 1] = T [j];
n
n
T [i] = e;
nk
la valeur de la variable
k -ime itration de la boucle tant que. Si N = 0 ou N = 1 alors N > 1. Si N est pair alors on peut vrier que nk = 2k N , si k1 nk = 2 (N 1). Dans les deux cas la suite (nk ) crot vers + partir de son deuxime n
la donc la condition d'arrt du
terme si
N {0, 1}, /
Calculer le rsultat de l'algorithme 7 sur plusieurs exemples permet de remarquer qu'il calcule
Nous le
1.3
Sance 3 (17/10/2007)
k -ime itration de la boucle tant que, n et m en galits mathmatiques sur
nk
et
mk
et
la
on les
transforme les lignes de l'algorithme faisant intervenir les variables termes des suites
donne :
Lignes 5 et 6 : m m n
donne :
1 2 3 4 5 6 7 8 9 10 11 12
dbut
n, m
entiers
n N; m M;
n
Lignes 7 et 8 : n n m
k, mk nk
mk+1 = mk nk+1 = nk mk
On peut alors utiliser ces galits mathmatiques pour dmontrer les proprits demandes. Appelons mk (respectivement nk la valeur de la variable m (resp. n) la k -ime itration de la boucle tant que et montrons par rcurrence que k mk 0. Initialisation : m0 = M 0 Hrdit : Supposons qu' un certain rang k mk > 0 et montrons que mk+1 > 0. Deux cas se prsentent : si sinon,
rcurrence.
La proprit tant initialise et hrditaire, elle est vraie pour tout De mme on dmontre que Montrons maintenant que prsentent : si donc la sinon,
de
N.
k N, nk 0.
dcroit pendant l'excution de l'algorithme, en calculant
mk+1 mk .
Deux cas se
mk > nk , mk+1 mk = mk nk mk = nk 0 mk+1 mk = mk mk = 0 0 suite (mk ) est dcroissante (pas ncessairement strictement). (nk )
est dcroissante (pas ncessairement strictement).
nm
et
mn
|n m|
rement monotone non plus, on peut le prouver en exhibant un contre-exemple. En initialisant avec
N = 10
et
M = 9,
on obtient :
k nk mk m k nk |mk nk |
0 10 9 1 1
1 1 9 -8 8
2 1 8 -7 7
Aucune des expressions proposes pour le moment ne nous permet donc de conclure quant l'arrt de l'algorithme 8. La stricte dcroissance de la suite valeurs entires Fixons
n + m va nous permettre de le prouver. k N, et notons uk = nk + mk . Deux cas se prsentent : si mk > nk alors uk+1 uk = mk+1 +nk+1 mk nk = mk nk +nk mk nk donc uk+1 uk = nk < 0 puisque nk > 0. sinon, uk+1 uk = mk+1 + nk+1 mk nk = nk mk + mk mk nk = mk < 0 puisque mk > 0. Dans tous les cas, tant que l'algorithme ne s'arrte pas, la suite (uk ) est strictement dcroissante, et valeurs entires. Elle nira donc par atteindre 0 un certain rang kf et on aura alors nkf = 0 et mkf = 0, ce
mn
N.
http://fr.wikipedia.org/wiki/Coefficient_binomial
n=0
coefBin pour calculer la valeur dans une certaine case (n, p), celui-ci renvoie 1 s'il est sur un des bords du triangle de Pascal, sinon il appelle rcursivement coefBin pour calculer les valeurs dans la case situe au-dessus, (n 1, p), et celle au-dessus gauche, (n 1, p 1).
A chaque appel de l'algorithme On va de nouveau chercher une expression entire qui dcroit chaque appel rcursif pour prouver l'arrt de l'algorithme. Les donnes chaque appel rcursif tant
et
N,
f : N2 N
strictement dcroissante.
la fonction suivante :
(n, p) n
dcroissante. Le problme est que cela nous permet seulement d'en conclure qu'elle atteindra forcment 0, ce
n = 0,
ce qui ne correspond pas l'arrt des appels rcursifs (qui a lieu quand
p=0 ou n=p).
Il
(n, p) n p est dcroissante mais pas strictement, elle ne convient donc pas non plus. p (n, p) Cn = coefBin(n,p) conviendrait, encore faut-il le prouver, ce qui n'est pas complteet il resterait alors prouver que quand elle atteint 1 on a bien p = 0 ou n = p.
f : (n, p) n + p. Eectivement, pour le premier appel rcursif, on a f (n 1, p 1) f (n, p) = n 1 + p 1 (n + p) = 2 < 0. Pour le second appel rcursif on a f (n 1, p) f (n, p) = n 1 + p (n + p) = 1 < 0. Donc dans tous les cas n + p dcrot chaque appel rcursif. Etant valeurs entires, elle atteindra donc forcment 0, ce qui impliquera p = 0.
Chapitre 2
Invariants
2.1
Sance 4 (19/10/2007)
l'tape
k+1
de l'excution, plus formellement c'est une dmonstration par (respectivement, une ingalit
rcurrence qu'il faut eectuer pour montrer que l'invariant est valable chaque tape. Rappelons que pour dmontrer une galit
A=B
M Z est strictement dcroissante ( la k + 1-ime itration de la Mk+1 Zk+1 = Mk Zk Zk 2 < Mk Zk ) et valeurs entires. Elle deviendra donc forcment
Z = 2I + 1. Zk (respectivement Ik ) la valeur de la variable Z tant que. Montrons par rcurrence sur k que k N, Zk = 2Ik + 1. Initialisation : au rang 0, 2I0 + 1 = 0 + 1 = 1 = Z0 . Hrdit : soit k N, 2Ik + 1 = Zk 2Ik+1 + 1 = Zk+1 ?
Pour cela appelons
I)
la
k -ime
boucle
(d'aprs l'algorithme)
Donc la proprit est intialise et hrditaire, elle est donc vraie pour tout bien dmontr. Montrons l'invariant
k N,
et l'invariant
2I + 1 = Z
est
M = N I 2.
tant que.
que
(algo)
= Mk Z k N + = Mk (N =0
2 Ik )
2 Ik
+ 2Ik + 1
Zk + 2Ik + 1
Donc la proprit est intialise et hrditaire, elle est donc vraie pour tout est bien dmontr. Montrons l'invariant
k N,
et l'invariant
M = N I2
M 0. Il n'y a mme pas besoin de rcurrence : pour k = 0, M0 = N 0 et k 1, Mk = Mk1 Zk1 0 d'aprs la condition de la boucle tant que, donc on a bien k 0, Mk 0.
Montrons que
I 2 N < (I +1)2 . Pour cela montrons qu'en n d'algorithme on a N I 2 0 et (I +1)2 N > 0. N I = M 0 d'aprs le deuxime et le troisime invariant. (I +1)2 N = I 2 +2I +1N = 2I +1M = Z M
2
d'aprs les deux premiers invariants. Or la n de l'algorithme la condition d'arrt de la boucle n'est pas vrie donc
tant que
Z M > 0,
en passant la racine :
N <I +1I =
tant que,
et donc l'algorithme
Ai
(respectivement
itration de la boucle
I H
au rang 0, soit
Donc la proprit est intialise et hrditaire, elle est donc vraie pour tout est bien dmontr. Montrons par rcurrence sur
I H
i que i N, Bi = 3(X Ci )2 . 2 2 au rang 0, B0 = 0 = 3(X X) = 3(X C0 ) . 2 2 soit i N, Bi = 3(X Ci ) Bi+1 = 3(X Ci+1 ) ?
2 2
(algo)
Donc la proprit est intialise et hrditaire, elle est donc vraie pour tout est bien dmontr. Montrons par rcurrence sur
i N, et l'invariant Bi = 3(X Ci )2
I H
3 3 3
(h.r.+ questions prcdentes)
Donc la proprit est intialise et hrditaire, elle est donc vraie pour tout est bien dmontr. A la n de l'algorithme 13, qui renvoie
i N,
et l'invariant
Zi = (X Ci )3
Z,
on a
C = 0,
(X 0)3
c'est dire
2.2
Sance 5 (24/10/2007)
tant que.
la n de la
i ni fi
0 10 7!
que.
N = 10 > 7,
en appelant
ni
(respectivement
fi )
la valeur de la variable
3 7 7! 10 9 8 fi 10!
chaque tape, il surait de multiplier par : : 10, 10 9, 9!, 8!, 7!, ce
10 9 8.
ni !. Ainsi si f0 n0 ! = 7!N !.
fi ni !,
N < 7. Il s'agit maintenant de le i que i N, ni !fi = 7!N !. I la proprit est trivialement vraie pour i = 0. H soit i N, ni !fi = 7!N ! fi+1 ni+1 ! = 7!N ! ? Si ni > 7 alors ni+1 !fi+1 = (ni 1)!ni fi = ni !fi = 7!N ! ni+1 ! 7!N ! fi par l'hypothse de rcurrence. Sinon, ni+1 !fi+1 = ni+1 ! ni+1 = ni +1 ni ! = 7!N !. Ainsi la proprit voulue est bien initialise et hrditaire, elle est donc vraie sur tout N. On dduit de cet 7!N ! invariant qu' la n de l'algorithme on renvoie fi = ni avec ni = 7, donc l'algorithme 7 renvoie fi = N !.
On peut vrier sur un exemple que l'invariant semble aussi vri pour dmontrer. Montrons donc par rcurrence sur
M = 48 m
et
et
N = 30,
n)
la
i-ime
excution de la boucle
tant que.
en appelant
mi
(respectivement
ni )
la valeur de
i 0 1 2 3 4 5
m 48 18 18 6 6 6
n 30 30 12 12 6 0
diviseurs communs
Un invariant semble tre que l'ensemble des diviseurs communs rithme, dmontrons-le. Supposons qu'il existe itration de la boucle diviseur commun de invariant on a
divisant
mk = m q
et
nk = n q ,
que mk > nk , et qu'il y a une k + 1-ime n ). nk+1 = nk = n q donc q est encore un reste constant appliquant cet
mk+1
k = 0 et k = h, h tant la dernire itration de la boucle tant que avant l'arrt de l'algorithme, {d N/d|M et d|N } = {d N/d|mh et d|0}. En considrant le maximum de ces ensembles, on obtient pgcd(M, N ) = pgcd(mh , 0) = mh , ce qui dmontre bien la correction de l'algorithme.
nk+1 . Ainsi on a montr que l'ensemble des diviseurs communs {d N/d|mk et d|nk } constant pour tout k . En particulier en
Remarques :
Cet algorithme s'appelle l'algorithme de PGCD par dirences successives. On utilise classiquement l'algorithme d'Euclide, par divisions successives, pour calculer le PGCD. Eectivement l'algorithme par dirences successives peut avoir une complexit assez mauvaise, regardez par exemple ce qui se passe quand on essaie de calculer PGCD(n, 1).
10
r3k )
la valeur de la variable
(respectivement
r1 , r2 , r3 )
la n de la
k -ime
itration de la boucle
tant que.
r1k , r2k ,
Pour
1 2 3 4 5 0 1 1 2 3 1 1 2 3 5 1 2 3 5 8 1 2 3 4 5
6 5 8 13 6 r1i =
bo(i),
r2i =
bo(i + 1) et
r3i =
r1 ,
puis le reste.
i que i N, r1i = bo(i). I au rang 1, r11 = 1 = bo(1). H soit i N, k i, r1k = bo(k) r1i+1 = bo(i + 1) ? r1i+1 = r2i = r3i + r2i1 = r1i + r1i1 = bo(i + 1). i
et donc On peut en dduire les deux autres ingalits :
Ainsi l'galit est initialise et hrditaire, elle est donc vraie pour tout
i N, r2i = r1i+1 =
bo(i
+ 1),
et
bo(i
1),
i = 0.
i que i N, r1i = bo(i), r2i = bo(i + 1), et r3i = bo(i 1). r11 = 1 = bo(1), r21 = 1 = bo(2), et r31 = 0 = bo(0). soit i N, r1i = bo(i), r2i = bo(i + 1), et r3i = bo(i 1) r1i+1 = bo(i + 1), r2i+1 = bo(i + 2), et r3i+1 = bo(i) ? r1i+1 = r2i = bo(i + 1) (par h.r.). r3i+1 = r1i = bo(i) (par h.r.). r2i+1 = r3i+1 + r2i = bo(i)+ bo(i + 1) (par galit prcdente et h.r.) donc r2i+1 = bo(i + 2). Ainsi les trois galits sont initialises et hrditaires, donc vraies pour tout i de N.
I H
au rang 1,
En n d'algorithme
i = n,
r1 .
2.3
Sance 6 (26/10/2007)
dbut
entier.
i 1;
T [i] = e);
Dmontrons les trois et utilisons-les chacun pour dmontrer la correction de l'algorithme. Appelons ik la valeur
k -ime
itration de la boucle
tant que.
Invariant 1
Montrons par rcurrence sur
Initialisation : au rang k = 1, on a excut la boucle tant que une fois, donc on a bien T [1] = e.
11
que
k 1, j [1, ik 1], T [j] < e, et que la boucle tant que T [ik ] < e, donc en ajoutant cette ingalit celles de l'hyptohse de rcurrence on obtient k 1, j [1, ik ], T [j] < e. La proprit tant initalise et hrditaire, elle est vraie pour tout k 1, c'est dire si la boucle tant que
: supposons qu' un certain rang s'excute
Hrdit
k
k -ime
s'excute une fois ou plus. Prouvons maintenant la correction de l'algorithme. S'il renvoie trouv une case du tableau, la i-ime, qui contient l'un des deux termes de la conjonction est faux : soit soit
e.
S'il renvoie
Vrai, alors i N et T [i] = e, on a donc bien Faux, alors (i N et T [i] = e) est faux, donc
i > N , alors l'invariant dmontr arme qu'aucune des N cases du tableau ne contient e. i N et T [i] = e. L'algorithme s'est arrt, donc est sorti de la boucle, donc la condition de boucle T [i] < e n'tait pas vrie, donc T [i] > e. Or le tableau contient des entiers rangs par ordre croissant donc e n'est pas contenu dans la i-ime case ni aucune droite. D'autre part l'invariant nous arme directement que e n'est contenu dans aucune des i 1 premires cases. Finalement e n'est dans aucune des N cases du tableau.
Invariant 2
Au dbut
k -ime
itration de la boucle
tant que
on teste que
T [ik1 ] < e.
Or
ik1 = ik 1
d'aprs
k 1, T [ik 1] < e.
Prouvons maintenant la correction de l'algorithme. S'il renvoie trouv une case du tableau, la i-ime, qui contient l'un des deux termes de la conjonction est faux : soit
e.
S'il renvoie
Vrai, alors i N et T [i] = e, on a donc bien Faux, alors (i N et T [i] = e) est faux, donc
case du tableau contient une valeur
i > N,
i 1-ime
e,
e n'est pas contenu dans le tableau. i N et T [i] = e. L'algorithme s'est arrt, donc est sorti de la boucle, donc la condition de boucle T [i] < e n'tait pas vrie, donc T [i] > e. Or le tableau contient des entiers rangs par ordre croissant donc e n'est pas contenu dans la i-ime case ni aucune droite. D'autre part l'invariant nous arme que T [i 1] < e, et le tableau est rang par ordre croissant, donc e n'est contenu dans aucune des i 1 premires cases. Finalement e n'est dans aucune des N cases du tableau.
le tableau est rang dans l'ordre croissant, donc
On a donc bien dmontr que l'algorithme est correct. Remarquons que l'invariant 2 tait plus direct dmontrer (sans rcurrence), mais demande quelques lignes supplmentaires pour la preuve de correction. Lorsqu'on demande un invariant il est possible qu'il y ait plusieurs possibilits, il s'agit d'en choisir un qui soit susamment simple dmontrer et utiliser pour la preuve de correction. Prcisons aussi que l'invariant a t dmontr dans tous les cas o la boucle
une fois.
Ceci dit le cas o elle ne s'excute pas ne pose pas de problme, les preuves de correction restent
valides, on peut juste se dbarasser de ce qui suit le qui ne sont alors pas dnies puisque
D'autre part
i = 1).
p, i,
entiers.
n
n renvoyer p;
12
L'invariant est
p = mi.
Appelons
p1 = 0 = m 0 = mi0 . pk = mik pk+1 = mik+1 ? pk+1 = pk + m = mik + m = m(ik + 1) = mik+1 Ainsi la proprit est initialise et hrditaire, donc vraie pour tout k , et l'galit
invariant de l'algorithme.
I H
que
pk , ik , les pk = mik .
valeurs de
et
au dbut de la
k -ime
boucle
tant que
et
e,
e,
>e
par
e .
13
Chapitre 3
Complexit
3.1
Sance 6 (26/10/2007)
n1
aectations
passe de 0
B,
il y a donc
2 + 2B
aectations,
multiplications et
additions, mais
On peut proposer un algorithme plus ecace de calcul de puissance, c'est l'algorithme d'exponentiation rapide 1 , qui a une complexit de O(log B) multiplications au lieu de O(B) pour calculer AB . Vous pouvez vous
p, i, x,
entiers.
p 1; x A; i B ;
n
n renvoyer p;
x x x; i i/2;
1 http://fr.wikipedia.org/wiki/Exponentiation_rapide
14
Chapitre 4
Listes chanes
4.1
Sance 9 (14/11/2007)
(c)
(d)
(e)
(f )
(g)
(h)
(i)
(j)
(k)
(l)
15
(m)
(n)
Fig. 4.1
Utilisations de listes chanes : aprs la ligne 1 (a), 2 (b), 3 (c), 4 (d), 5 (e), rorganisa-
tion (f), aprs la ligne 6 (g), rorganisation (h), aprs la ligne 7 (i), 8 (j), 9 (k), rorganisation (l), aprs la ligne 10 (m), 11 (n).
4.2
Sance 10 (28/11/2007)
i indiquant un numro de case 1, puis le faire varier l'aide d'une boucle pour tout tant que jusqu' un entier n correspondant au nombre de cases du tableau. Sur les listes chanes, le parcours peut se faire l'aide d'une boucle tant que comme illustr en gure 10
(on peut aussi eectuer le parcours par une fonction rcursive mais il est possible que ce soit plus dlicat).
Donnes : L, . . . : liste simplement chane, . . . Rsultat : renvoie un truc aprs avoir parcouru L. dbut
Variables :
Q,
Q L;
...;
succ;
n n
...;
...;
Attention la condition d'arrt, on pourra prfrer s'arrter aprs avoir atteint le dernier lment, c'est dire quand
succ = NULL.
Q,
Q L;
Quand ce n'est pas prcis dans les exercices sur les listes,
16
Donnes : L : liste simplement chane Rsultat : modie L pour dplacer son premier lment en dernire position
Variable :
dbut
Q,
Q L; si Q = NULL
crerListe(L
info, NULL);
Q,
Q L; si Q = NULL
0(n2 )
En utilisant une liste doublement chane, l'ide est que la suppression peut se faire en temps constant (comme on a alors accs l'adresse du dernier lment, il sut de faire pointer le successeur de cet lment vers le successeur de son successeur). Ainsi la complexit totale de SupprimeValeur en utilisant une liste doublement chane serait en
O(n).
4.3
Sance 11 (07/12/2007)
O(n2 )
qui ne stocke pas la valeur de l'lment prcdent, mais carrment l'lment prcdent lui-mme, permettant d'atteindre une complexit en
O(n).
17
Donnes : L : liste simplement chane Rsultat : Modie L en supprimant tous ses doublons, c'est dire ses lments qui auraient mme
valeur que leur successeur
dbut
Variable :
Q,
Q L; si L = NULL
alors
n
n
n
n
Donnes : L : liste simplement chane Rsultat : Modie L en supprimant tous ses doublons, c'est dire ses lments qui auraient mme
valeur que leur successeur
dbut
Variable :
Q,
Q L; si L = NULL
n
n
n
n
P Q; Q Q succ; si Q info = P info alors P succ Q succ; //on supprime de L l'lment point par Q.
18
Q, M ,
Q L; M L; si L = NULL alors M crerListe(L info,NULL); tant que Q succ = NULL faire Q Q succ; M crerListe(Q info,M );
n
n n renvoyer M ;
sans crer de nouvelle liste. Pour cela on va faire avancer le long de la liste trois pointeurs sur trois lments conscutifs de la liste modier, pour garder en mmoire leurs adresses et pouvoir faire les modications.
Donnes : L : liste simplement chane Rsultat : Modie L pour inverser l'ordre de ses lments dbut si L = NULL alors
Variables :
Q, R, S ,
n
n
n
faire
dsigne son dernier lment, et pour rcuprer par exemple la valeur de son premier lment on
info. Quelles fonctions appliquer pour crer une liste doublement chane 2 lments, contenant les valeurs 4 et
19
Donnes : L1, L2 : listes simplement chanes Rsultat : renvoie L1 qui on a concatn L2 dbut si L = NULL alors renvoyer L2; n sinon
Q L;
Variable :
Q,
renvoyer L1;
L2;
L crerTriplet(NULL,NULL,NULL); Q crerTriplet(L, 4, L); L succ Q; L pred Q; R crerTriplet(L pred, 6, L); Q succ R; L succ Q; L pred R;
Sur la liste doublement chane ainsi cre, comment supprimer le dernier lment pour obtenir une liste doublement chane 1 lment (contenant donc la valeur 4) ? Par exemple on applique l'algorithme 20.
L pred Q; Q succ L;
4.4
O(n).
O(1).
20
Donnes : L : liste doublement chane Rsultat : Renvoie une liste constitue des lments de L dans l'ordre inverse dbut
Variables :
P , Q,
//On traite l'lment P en inversant son successeur stock dans Q avec son prdcesseur:
P pred; Q; //On traitera Q, l'ancien successeur de P , la prochaine tape: P Q; Q Q succ;
faire
n
n
n renvoyer L;
P P
succ pred
P Q;
pred;
Donnes : L1, L2 : listes doublement chanes Rsultat : Renvoie une liste constitue des lments de L1 puis de ceux de L2 dbut si L1 succ = NULL alors renvoyer L2; n sinon si L2 succ = NULL alors renvoyer L1; n sinon
pred L1 succ L2 pred L2 pred; pred succ L1; renvoyer L1;
succ pred
L2 L1 L1 L1
pred;
succ;
21
Chapitre 5
Arbres
5.1
Sance 12 (12/12/2007)
1)
d'un arbre binaire sont appels feuilles, ils pointent vers NULL gauche et NULL droite. Pour parcourir une liste, on pouvait partir de la tte et suivre les pointeurs vers les successeurs jusqu' arriver la n de la liste et donc un pointeur vers NULL l'aide d'une boucle une boucle l'arbre. Comment crer un arbre de racine tiquete 2 ayant deux ls tiquets 1 et 3 ? crerArbre(2,crerArbre(1,NULL,NULL),crerArbre(3,NULL,NULL))
tant que. Avec un arbre utiliser tant que est beaucoup moins naturel, et on prfrera employer des algorithmes rcursifs : savoir
rsoudre un problme sur le sous-arbre gauche et le sous-arbre droit permettre de rsoudre le problme sur
Donnes : A : arbre binaire Rsultat : renvoie la hauteur de l'arbre A dbut si A = NULL alors renvoyer 0; n sinon si A sag = NULL et A sag = NULL alors renvoyer 0; n sinon renvoyer 1 + max Hauteur(A sag),Hauteur(A sad) ; n n Algorithme 23 : Hauteur(A : arbre binaire) : entier
22
Donnes : A : arbre binaire Rsultat : nombre de feuilles de l'arbre A dbut si A = NULL alors renvoyer 0; n sinon si A sag = NULL et A sag = NULL alors renvoyer 1; n sinon renvoyer NombreFeuilles(A sag)+NombreFeuilles(A sad); n n Algorithme 24 : NombreFeuilles(A : arbre binaire) : entier
5.2 Sance 13 (12/12/2007, 13/12/2007)
n,
a,
f.
Retenez que si un
(n).
permettent de le dmontrer, ainsi que les petits raisonnements qui permettent de les retrouver. Tout noeud sauf la racine a un pre, on peut donc lui associer l'arte qui vient sur lui. Ainsi, on dnit une bijection entre tous les noeuds sauf la racine avec toutes les artes. Donc pour tout arbre. Pour la formule sur le nombre de feuilles, on va se restreindre aux arbre strictement binaires, c'est dire ceux dont aucun noeud interne n'a qu'un ls, en remarquant qu'ils peuvent se construire de la faon suivante. On initialise l'arbre un noeud isol ( la fois racine et feuille). Puis on applique la rgle suivante : on choisit une feuille, on lui accroche deux feuilles (une " une feuille pour en ajouter deux, donc comme
a = n 1.
cerise ").
Appelons
nk k -ime
(respectivement
ak , fk ),
le nombre de Ainsi,
fk+1 = fk + 1.
a1 = 2
et
f1 = 2
ak = 2k
et
fk = k + 1 ,
donc
ak+1 = ak + 2. ak = 2fk 2.
a = n 1 = 2f 2
Ainsi, on a bien
a = O(n)
et
f = O(n).
p1
p1
dans
p1
p1
dans
23
Donnes : A : arbre binaire, p : entier Rsultat : renvoie le nombre de nuds de profondeur p de l'arbre A dbut si p = 0 et A = NULL alors renvoyer 1; n sinon si A = NULL alors renvoyer 0 n sinon renvoyer NombreNudsProfondeur(A sag, p 1)+NombreNudsProfondeur(A sad, p 1); n n Algorithme 25 : NombreNudsProfondeur(A : arbre binaire, p : entier) : entier
Donnes : A : arbre binaire Rsultat : modie A en l'eeuillant dbut si A saq = NULL et A sad = NULL alors
A
NULL
n si (A sag = NULL) alors si (A sag sag = NULL) et (A sag sad = NULL) alors n sinon n
A
sag
NULL
Eeuille(A
sag );
n si (A sad = NULL) alors si (A sad sag = NULL) et (A sad sad = NULL) alors n sinon n n
A
sad
NULL
Eeuille(A
sad);
n
24
Chapitre 6
Autres structures de donnes
6.1
Sance 14 (14/12/2007)
Donnes : A : arbre Rsultat : Renvoie une liste contenant la notation postxe correspondant l'arbre A dbut si A = NULL alors renvoyer NULL; n sinon si A sag = NULL et A sad = NULL alors renvoyer crerListe(A info,NULL); n sinon si A sag = NULL alors renvoyer Concatner Postxe(A sad),crerListe(A info,NULL) ; n sinon si A sad = NULL alors renvoyer Concatner Postxe(A sag),crerListe(A info,NULL) ; n sinon renvoyer Concatner Postxe(A sad),Concatner(Postxe(A sad),crerListe(A n n
info,NULL)) ;
n
25
Donnes : P : pile contenant une notation postxe dont le dernier lment est en haut de la pile Rsultat : Renvoie la valeur de l'expression dont la notation postxe est stocke dans P dbut si PileVide?(P ) alors renvoyer 0; n sinon
Variables :
R1, R2
: entiers,
operation
: symbole.
n
n
operation sommetPile(P ); dpiler(P ); si operation = + ou operation = alors R1 Evaluer(P ); //P est alors modie ! R2 Evaluer(P ); renvoyer R1 operation R2;
Breadth-First Search
k + 1,
parcours en largeur
k,
suivi d'un
T1
et
T 2,
T1
et
T 2,
Ide de l'algorithme 30 : pour chacun des m lments du premier tableau, on regarde en O(n) s'il est
n
lments du second tableau (si oui on l'ajoute une liste d'lments de l'intersection des
O(mn).
c'est dire des lments gaux du premier tableau qui appartiendraient aussi au second, ou inversement. Pour cela on utilise en particulier l'algorithme 13 pour la fonction calculer la taille de la liste en tableau, on regarde en donc en
est quadratique en la taille de la liste d'lments de l'intersection des deux tableaux, c'est dire
O(m2 ). Il reste
Ide de l'algorithme 31 avec un des deux tableaux tri : pour chacun des m lments du premier
O(log n)
s'il est prsent parmi les lments du second tableau qui sont tris (le tri du
O(m).
c'est dire
O(n log n)), par dichotomie. La complexit O(max(m, n) log n), (et O(m log n) si on
tableau est dj tri) elle est meilleure qu'avec l'ide prcdente. Attention toutefois la procdure de suppression des doublons que j'ai opportunment omise. Si on la ralise, sa complexit est en complexit de second en
Ide de l'algorithme 32 avec les deux tableaux tris : on trie le premier tableau en O(m log m), le
O(n log n), puis on parcourt simultanment les deux tableaux. La complexit totale est en O(n log n+ m log m + m + n), soit O(max(m, n) log max(m, n)), ce qui est encore meilleur que l'ide prcdente. Si en plus on considre que les tableaux sont dj tris, on obtient alors une complexit en O(m + n).
26
Donnes : A : arbre Rsultat : Renvoie une liste chane correspondant au parcours en largeur de A dbut
Variables :
L,
liste chane,
F,
le.
info,L);
//On ajoute la n de la le les ls ventuels, traiter plus tard : si A sag = NULL alors
n n
n
//La liste L a t construite dans le mauvais sens, son premier lment est celui visit en dernier, //donc de profondeur maximale dans A :
renvoyer Miroir(L);
Algorithme 29 : ParcoursLargeur(F
27
Donnes : T 1, T 2 : tableaux de respectivement m et n entiers Rsultat : Renvoie le nombre d'entiers prsents dans les deux tableaux.
Variables :
dbut
L,
liste chane ;
t,
entier.
pour i de 1 m faire
j 1;
NULL;
succ,Q
info);
n
//Taille de la liste L :
Q L; t 0;
n
Donnes : T 1, T 2 : tableaux de respectivement m et n entiers, T 2 est tri Rsultat : Renvoie le nombre d'entiers prsents dans les deux tableaux.
Variables :
dbut
L,
liste chane ;
t,
entier.
NULL;
succ,Q
info);
n
//Taille de la liste L :
Q L; t 0;
n
Donnes : T 1, T 2 : tableaux tris de respectivement m et n entiers Rsultat : Renvoie le nombre d'entiers prsents dans les deux tableaux.
Variables :
dbut
d, t,
entier.
i 1; j 1; d 0; t 0;
tant que i < m et j < n faire si T 1[i] = T 2[j] alors si T 1[i] = d alors
n
i i + 1; j j + 1;
j j + 1;
n
29