Documente Academic
Documente Profesional
Documente Cultură
Philippe Gambette
5 juin 2009
1 3
3 3 4 4 4 4 4 6 6 6 7 7 7
Sance 2 (01/10/2008) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mthodologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Algorithme 3 - SSTableauVide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Algorithme 4 - LignesEgales? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Algorithme 5 - InsrerTabTri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mthodologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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 (08/10/2008) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.1 2.1.2 2.1.3 2.2 2.3 2.2.1 2.3.1 2.3.2 Les invariants, quoi a sert ? Invariants de l'algorithme 15 Invariants de l'algorithme 13 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
9 9 9 10 11 11 12 12 12
Sance 5 (13/10/2008) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invariant et correction de l'algorithme 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . Correction de l'algorithme 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Correction de l'algorithme de recherche squentielle en tableau tri . . . . . . . . . . . . Sance 6 (15/10/2008) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3 Complexit d'algorithmes
3.1 Sance 7 (20/10/2008) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.1 3.1.2 3.1.3 3.2 3.2.1 3.2.2 3.2.3 3.2.4 3.3 3.3.1 3.3.2 3.4 3.4.1 3.4.2 3.4.3 3.5 3.5.1 Mthodologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Complexit de l'algorithme 15 (exercice 1) . . . . . . . . . . . . . . . . . . . . . . . . . . Complexit de l'algorithme 16' (exercice 3 complexit) . . . . . . . . . . . . . . . . . . . Arrt et complexit de l'algorithme 12 (exercice 2 complexit) . . . . . . . . . . . . . . . Arrt et complexit de l'algorithme 13 (exercice 2 invariants) . . . . . . . . . . . . . . . Arrt et complexit de l'algorithme 9 (exercice 3 arrt) . . . . . . . . . . . . . . . . . . . Complexit de la recherche dichotomique (exercice 3 algorithme et preuves) . . . . . . . Algorithme indicePrdcesseur (exercice 4 algorithme et preuve) . . . . . . . . . . . . .
14
14 14 14 14 15 15 15 15 16 16 16 16 17 17 17 18 18 18
Sance 8 (22/10/2008) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Sance 9 (03/11/2008) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Test de tri d'un tableau (exercice 4 complexit) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Algorithme d'valuation d'un polynme (exercice 5 complexit) . . . . . . . . . . . . . . Algorithme de plus long prxe suxe (exercice 7 complexit) Exponentiation rapide (exercice 6 complexit) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exponentiation rapide - version rcursive (exercice 6 complexit) . . . . . . . . . . . . .
Sance 10 (05/11/2008)
Sance 11 (12/11/2008)
3.5.2
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
4 Listes chanes
4.1 Sance 12 (17/11/2008) 4.1.1 4.1.2 4.1.3 4.2 4.2.1 4.2.2 4.3 4.3.1 4.3.2 4.3.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Algorithmes sur les listes chanes Familiarisation avec les listes chanes
22
22 22 22 22 23 23 23 26 26 26 26
Adresse de la dernire cellule d'une liste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Premier lment mis la n d'une liste
Sance 13 (19/11/2008)
Sance 14 (26/11/2008)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Suppression de doublons conscutifs d'une liste . . . . . . . . . . . . . . . . . . . . . . . Concatnation de deux listes simplement chanes Concatnation de deux listes doublement chanes
5 Arbres
5.1 5.2 Fin de la sance 14 (26/11/2008) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.1 5.2.1 5.2.2 5.2.3 Familiarisation avec les arbres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Hauteur d'un arbre binaire Sance 15 (03/12/2008)
28
28 28 28 28 28 29
6 Tris
6.1 Sance 16 (10/12/2008) 6.1.1 6.1.2 6.2 6.2.1 6.2.2 6.2.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Taille de l'intersection de deux tableaux d'entiers . . . . . . . . . . . . . . . . . . . . . . Test de l'existence de doublons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
30
30 30 32 32 32 32 32
Sance 17 (17/12/2008)
Avertissement
Ce document peut contenir des erreurs, indiquez-les moi
de gagner un bonus pour la note de participation). 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. Les cours d'algorithmique de L1 sont disponibles sur l'espace pdagogique (unit FLIN 101).
AT X pour que vous puissiez participer la rdaction de ce corrig est Les indications sur l'utilisation du langage L E disponible avec le chier source de ce document l'adresse http://www.lirmm.fr/~gambette/EnsAlgo.php.
Chapitre 1
Rvisions, preuves d'arrt
1.1
Sance 1 (29/09/2008)
i 1, n
n
P P T [1];
T [i];
: entier)
On pouvait aussi procder en utilisant une boucle variable de boucle, et l'incrmenter chaque itration.
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]|. P P T [1]; i 2; tant que i n faire si |x T [i] < |x P P | i i + 1;
et
i 1, n
alors P P
T [i];
n
n
: entier)
Pensez vrier votre algorithme sur un exemple si vous avez le temps. Vous devez aussi tre capable de le dcrire en quelques phrases, par exemple pour celui-l : on parcourt les cases du tableau en gardant en mmoire chaque tape le meilleur lment trouv jusqu' maintenant pour le comparer avec l'lment de la case courante. Remarquez aussi que la condition remplaant cette condition par
|x T [i] < |x P P |
qui rpond la question. On aurait pu renvoyer le dernier lment du tableau qui rpond la question en
|x T [i] |x P P |.
renvoyer permet de terminer l'algorithme en arrtant les boucles en cours, une solution
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 3 : Somme?(d A[1..n] : tableau d'entiers, d B [1..n] : tableau d'entiers, d Som : entier)
boolen
1.2
Sance 2 (01/10/2008)
1.2.1 Mthodologie
On vous demande un algorithme que vous ne savez pas comment crire ? Prenez un exemple et tentez de voir intuitivement dessus comment rsoudre le problme. Tentez alors de gnraliser ces oprations pour obtenir les principes gnraux de votre algorithme. Puis traduisez ces principes en pseudo-code, le langage utilis pour dcrire un algorithme. Si besoin, quand vous cherchez les principes de base de votre algorithme, dcomposez le problme en sousproblmes que vous traitez indpendamment, comme pour l'algorithme
LignesEgales?.
c1 , c2 (ck
indique bien
sr un numro de colonne, et lk un numro de ligne) ainsi que la progression des variables qui permettent de
1 l1 l2 n
et
Faux),
renvoie
dbut pour tous les i de l1 l2 faire pour tous les j de c1 c2 faire si T [i, j ] alors renvoyer Faux; n n renvoyer Vrai; n Algorithme 4 : SousTabVide?(d T [1..n, 1..n] : tableau d'entiers, d l1 , l2 , c1 , c2
: entiers) : boolen
T [1..n, 1..n] j.
T [i, j ]
et
Si vous ne voyez pas comment procder, vous pouvez dcomposer votre algorithme LignesEgales? en :
un algorithme
CoupleLignesEgales?
i-ime
et la
j -ime,
rithme
un algorithme
LignesEgales1? (algorithme 6) qui, pour tout couple de lignes direntes, appelle l'algoCoupleLignesEgales?.
sont gales.
Donnes : T [1..n, 1..n] un tableau de 0 et de 1, i et j deux entiers tels que 1 i n et 1 j n Rsultat : Renvoie Vrai si et seulement si les lignes i et j de T sont identiques, c'est dire ssi dbut tant que k n et T [i, k] = T [j, k] faire si k = n alors renvoyer Vrai; sinon n renvoyer Faux; n
k k + 1; k 1, n
,
T [i, k ] = T [j, k ].
: entier ) : boolen
Tant que de l'algorithme CoupleLignesEgales? permet de l'arrter ds qu'on Pour : pour k de 1 n, si T [i, k] = T [j, k]. . . .
i
et
k -ime
j,
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 1 faire pour tous les j de i + 1 n faire si CoupleLignesEgales?(T, i, j ) alors renvoyer Vrai; n n n renvoyer Faux; n Algorithme 6 : LignesEgales1?(d T [1..n, 1..n] : tableau d'entiers) : boolen
Remarquez dans l'algorithme
i = j 1, n / k 1, n
T [i, k ] = T [j, k ].
: ceci permet
(i, j ) tels que i < j . On vite donc de tester si la ligne j = 1 est gale la ligne i = 2 aprs avoir test si la ligne i = 1 est gale la ligne j = 2. Cela permet donc de faire en gros deux fois moins d'tapes que la solution plus simple mais moins lgante suivante : pour tout i de 1 n, pour tout j de 1 n, si i = j alors . . .
en fait d'atteindre toutes les valeurs des couples Une fois que vous avez trouv les deux algorithmes permettant de rsoudre chaque partie dcompose du problme, vous pouvez les runir dans l'algorithme 7, en faisant bien attention au fait que stoppe l'algorithme (et donc il ne faut pas rcrire dans
CoupleLignesEgales?). Pour approfondir : remarquons que comme il y a trois boucles (deux pour et une tant que imbriques,
suivante : trier les lignes du tableau en
O(n2 log n)
de la manire
O(n)),
puis
parcourir chaque ligne du tableau pour vrier si elle est gale la suivante. On peut mme tre encore plus astucieux en reprsentant contient seulement des 0 et des 1) et en commenant par trier
Faux
par 0 et
Vrai
algorithme 41), avant de comparer chaque ligne avec la suivante, pour obtenir une complexit totale en
O(n2 ).
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 1 faire pour tous les j de i + 1 n faire
k 1; i = j 1, n / k 1, n
,
T [i, k ] = T [j, k ].
n
n
n + 1.
Donnes : T [1..n, 1..n] un tableau tri d'entiers. 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;
1.3
1.3.1 Mthodologie
Quand on vous demande de prouver l'arrt d'un algorithme, vous pouvez avoir l'impression qu'on peut le justier en dcrivant la partie de l'algorithme qui concerne l'arrt. Le problme est que vous paraphrasez gnralement l'algorithme avec force priphrases. Il est impossible de voir si vous avez vraiment compris dans le cas o vos explications seraient embrouilles. Bref, pour viter cela, il existe une mthode formelle que vous devez appliquer. Il s'agit de construire (ou d'identier) une expression calcule partir des variables de l'algorithme, qui dcrot strictement tout au long de l'algorithme, et qui est valeurs entires et positives. Cette expression n'apparat pas ncessairement parmi celles calcules dans l'algorithme, il vous faudra parfois jongler avec les variables et des additions, soustractions, multiplications, fractions, valeurs absolues, etc., pour construire cette expression. Une fois que vous avez trouv une bonne expression candidate. Appelons
uk
la
k -ime
itration de l'algorithme. Il faut montrer qu'elle vrie bien les proprits demandes. Le fait qu'elle
dcoule le plus souvent directement de la dnition. Pour la dcroissance stricte, il s'agit existe, alors
de montrer que si la
k + 1-ime itration de l'algorithme montrant uk+1 uk < 0 uk > 0, en montrant que uk+1 /uk < 1, ce
uk+1 < uk ,
uk
est
uk
est bien une expression valeurs entires positives qui dcrot strictement chaque pas (= intration)
de l'algorithme, on est certain que l'algorithme ne peut avoir un nombre de pas illimit, c'est dire qu'il a un nombre de pas limit, et donc qu'il s'arrte. Pour nir, remarquons que pour dsigner l'expression strictement dcroissante valeurs entires, nous utilisons le formalisme des suites. La premire tape de votre preuve d'arrt (de mme que les preuves d'invariants du chapitre suivant) sera donc toujours de dduire de l'algorithme des relations sur la valeur des variables au
k + 1-me
pas en fonction du
k -ime.
x,
xk
sa valeur la n du
pas. Puis vous utiliserez les aectations de l'algorithme pour exprimer la relation entre si chaque pas, la seule instruction concernant proprit sur la suite
est :
(xk )k0 : si xk > 0 alors xk+1 = xk 1 sinon, xk+1 = xk (ne pas oublier
a !)
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},
N !.
Nous le
1 2 3 4 5 6 7 8 9 10 11 12
n
En notant
mk
et
et
la
transforme les lignes de l'algorithme faisant intervenir les variables termes des suites
on les
(nk )
(mk ).
7
Lignes 3 : n N ; m M ;
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,
entier.
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 ne peut donc prendre qu'un nombre ni de valeurs, donc l'algorithme s'arrtera. On montre similairement que l'expression
mn
N.
Chapitre 2
Invariants
2.1
Sance 4 (08/10/2008)
l'tape
k+1
rcurrence qu'il faut eectuer pour montrer que l'invariant est valable chaque tape. Prcisons qu'une dmonstration par rcurrence permet de montrer qu'une proprit tout
P (k )
de
N.
Or si l'on parle de la
k -ime
l'algorithme s'est peut-tre arrt avant d'arriver sa faudrait dire que la proprit
P (k )
k -ime
itration de l'algorithme
est eectue. Nous abrgerons (et vous tes autoriss, et mme encourags, pour ne pas perdre de temps et surcharger vos copies, le faire) en valable pour tout Rappelons que pour dmontrer une galit
A=B
C'est mme trs fortement conseill pour viter des rdactions douteuses voire compltement fausses. . .
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.
boucle
tant que.
que
soit
= 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 =
Ai
(respectivement
i-ime
I H
Bi , Ci , Zi )
la valeur de la variable
(respectivment
B, C , Z )
la n de la
A0 = 1 = 3(X X ) + 1 = 3(X C0 ) + 1. i N, Ai = 3(X Ci ) + 1 Ai+1 = 3(X Ci+1 ) + 1 ? Ai+1 3(X Ci+1 ) + 1 = Ai + 3 3 X (Ci 1) = Ai + 3 3X + 3Ci 3 = Ai 3(X Ci ) =0
(h.r.) (algo)
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
i N, et l'invariant Bi = 3(X Ci )2
au rang 0,
i que i N, Zi = (X Ci )3 . Z0 = 0 = (X X )3 = (X C0 )3 .
10
soit
i N, Zi = (X Ci )3 Zi+1 = (X Ci+1 )3 ?
3
(algo)
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 (13/10/2008)
i 0 1 2 3 4 5
m 48 18 18 6 6 6
n 30 30 12 12 6 0
M = 48 et N = 30, en appelant mi (respectivement ni ) i-ime excution de la boucle tant que. diviseurs communs m et n {1, 2, 3, 6} {1, 2, 3, 6} {1, 2, 3, 6} {1, 2, 3, 6} {1, 2, 3, 6} {1, 2, 3, 6} semble tre que l'ensemble des diviseurs communs m et n reste constant au n)
la n de la
la valeur de
cours de l'algo-
rithme, dmontrons-le.
Dk = {d N/d|mk et d|nk } l'ensemble des diviseurs communs aux valeurs des variables m et n k -ime itration de la boucle tant que. On cherche donc montrer que k N, Dk = Dk+1 .
Rappelons que pour montrer une galit d'ensemble, il faut montrer que tout lment de l'un est dans l'autre, Supposons qu'il existe q Dk , c'est dire q vriant : m , n N tels que mk = m q et nk = n q . Si mk > nk , alors mk+1 = mk nk = q (m n ). nk+1 = nk = n q donc q est encore un diviseur commun de mk+1 et nk+1 . On a le mme rsultat si mk nk . Donc dans tous les cas, q Dk+1 Inversement, considrons q Dk+1 . Alors m , n N tels que mk+1 = m q et nk+1 = n q . Si mk > nk , alors n q = nk+1 = nk donc nk est aussi divisible par q . De plus, m q = mk+1 = mk nk donc mk = m q + nk = m q + n q = (m + n )q donc mk est aussi divisible par q . La preuve fonctionne de faon symtrique pour le cas mk < nk . Finalement, dans tous les cas, q Dk . Ainsi on a montr que l'ensemble des diviseurs communs reste constant tout au long de l'algorithme, soit Dk constant pour tout k . En particulier en appliquant cet invariant k = 0 et k = h, h tant la dernire itration de la boucle tant que avant l'arrt de l'algorithme, on a {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.
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).
11
2.3
Sance 6 (15/10/2008)
1)+bo(i 2) i
(respectivement
On commence par voir sur un exemple ce que calcule l'algorithme, en appelant ik (respectivement
r3k )
la valeur de la variable
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, r1 = 1 = bo(1). 1 H soit i N, k i, r1 = bo(k ) r1i+1 = bo(i + 1) ? k 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). H soit i N, r1 = bo(i), r2 = bo(i + 1), et r3 = bo(i 1) r1 i i i i+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.
au rang 1, En n d'algorithme
i = n,
r1 .
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.
12
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. Hrdit : supposons qu' un certain rang k 1, j [1, ik 1], T [j ] < e, et que la boucle tant que
k
fois. Alors au dbut de la
que
s'excute
k -ime
ingalit celles de l'hyptohse de rcurrence on obtient La proprit tant initalise et hrditaire, elle est s'excute une fois ou plus.
T [ik ] < e, donc en ajoutant cette k 1, j [1, ik ], T [j ] < e. vraie pour tout k 1, c'est dire si la boucle tant que
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).
13
Chapitre 3
Complexit d'algorithmes
3.1
Sance 7 (20/10/2008)
3.1.1 Mthodologie
La complexit d'un algorithme permet d'exprimer formellement sa rapidit en fonction de la taille des donnes en entre. Pour l'valuer nement, on compte prcisment le nombre d'oprations. Attention, lors du comptage, il faut tre prudent, et ventuellement vrier sur un exemple : si une variable
i i + 1,
n1
aectations au total.
terme dominant de l'expression du nombre d'oprations en fonction de la taille des donnes en entre. Si un algorithme
une dnition mathmatique base de limites, en pratique il faut retenir qu'elle correspond au eectue
O(. . .).
5n3 + 2n
n,
n3 ,
O(n )
O(n),
O(n2 ),
la complexit est quadratique, Si l'algorithme fait terme dominant est donc c'est
O( n).
O(log n), la complexit est logarithmique. n +log de grandeur de sa complexit ? Le 10 n tapes dans le pire des cas, quel est l'ordre n (pour avoir une intuition ce sujet, comparer 1000000 = 1000 log10 1000000 = 6),
passe de 0
multiplications et
additions, mais
B , il y a donc B excutions de la boucle tant que, et 2+2B aectations, B + 1 comparaisons (la dernire comparaison choue et fait sortir de la
boucle). d'
exponentiation rapide 1 , qui a une complexit de O(log B ) multiplications au lieu de O(B ) pour calculer AB .
Pour approfondir : on peut proposer un algorithme plus ecace de calcul de puissance, c'est l'algorithme
fois.
I = 2, . . . N fois pour I = N . N N (N +1) Finalement, le nombre total d'excutions de la ligne R R + 1; est donc i=1 i = 2
2 fois pour
I = 1,
(pour calculer,
utiliser le fait que c'est la srie d'une suite arithmtique, ou bien retrouver la formule l'aide d'un dessin). Il
N (N +1) + 1 aectations dans les lignes 1 et 2, et N (N + 1) + 1 + N = (N + 1)2 en comptant les 2 2 aectations chaches dans les boucles . La complexit en temps de l'algorithme est donc en O (N ), c'est
y a donc
Pour
dire quadratique.
1.
http://fr.wikipedia.org/wiki/Exponentiation_rapide
14
Donnes : A, B : entiers Rsultat : renvoie la puissance AB . Variables : p, i, x, entiers. dbut tant que i = 0 faire si i modulo 2 = 1 alors n
p p x; i i 1; p 1; x A; i B ;
n
n renvoyer p;
x x x; i i/2;
3.2
uk = Mk Zk
rithme il vaut
O( I ).
Ck
la valeur de
aprs la
k -ime
itration de la boucle
une suite strictement dcroissante valeurs entires, donc elle ne peut prendre qu'un nombre ni de valeurs, et donc l'algorithme s'arrte. Comme
est initialis
X,
O (X ).
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). La valeur de n dcrot strictement chaque appel rcursif et elle est entire. Donc dans chaque branche de l'arbre (binaire) d'excution de l'algorithme, n ne peut prendre qu'un nombre ni de valeurs. Ainsi, toutes
A chaque appel de l'algorithme les branches de cet arbre binaire ont une profondeur nie donc l'arbre d'excution est ni, donc il n'y a qu'un nombre ni d'appels rcursifs, et donc l'algorithme s'arrte.
15
e,
e,
c'est dire qu'on veut faire un lger changement d'invariant, il sut donc de remplacer dans l'algorithme
>e
par
e .
La complexit de cet algorithme de recherche dichotomique est logarithmique. Pour s'en convaincre, on peut reprsenter l'algorithme par un arbre de recherche : chaque appel de l'algorithme, on coupe l'intervalle de recherche en deux, puis on recherche rcursivement soit dans la partie de gauche, soit dans celle de droite. L'arbre est donc binaire (chaque tape donne naissance deux tapes possibles). Si 2, alors il a
log2 (n).
correspond justement la profondeur de l'arbre, et chaque tape se fait en temps constant, la complexit en temps est donc en Si
O(log n). n
qui est la puissance de 2 juste suprieure
(c'est dire
n =2
log2 (n) +1
O(log2 n ),
c'est dire en
n O(log n).
3.3
Sance 9 (03/11/2008)
Donnes : T [1..n] : un tableau d'entiers tri par ordre croissant, x : un entier Rsultat : renvoie 0 si tous les lments de T sont suprieurs ou gaux x, sinon renvoie le plus grand Variables : Deb, F in, M il, entiers. dbut tant que Deb F in faire si T [M il] < x alors sinon n
Deb M il + 1; F in M il 1; Deb 1; F in n; M il (Deb + F in) div 2;
indice
i [1..n]
tel que
T [i] < x.
n
La formule suivante, qui peut aussi tre reprsente sous forme d'un schma sur le dessin du tableau tri, est un invariant : La complexit est bien sr logarithmique.
le nombre maximum,
passe de 1
16
3.4
Sance 10 (05/11/2008)
Xi
et de le multiplier par
Donnes : X
: un entier,
a[0..n]
: un tableau de
n+1
polynme.
du polynme en
X.
n
Algorithme 13 : EvaluationPolynome(d X
: entier, d
a[0..n]
Donnes : T [1..n] : un tableau de n entiers, k : un entier Rsultat : renvoie VRAI si le prxe et le suxe de T de longueur k sont gaux dbut pour tous les i de 1 k faire si T [i] = T [n k + i] alors renvoyer FAUX; n renvoyer VRAI; n Algorithme 14 : SuxePrexeEgaux(d T [1..n] : tableau d'entiers, d k : entier) : boolen Donnes : T [1..n] : un tableau de n entiers Rsultat : renvoie la taille du plus long prxe gal au suxe de T dbut
Variable : Variable :
i,
un entier.
et dirent de
T.
k,
un entier.
k n;
n
n renvoyer k;
17
Donnes : T [1..n] : un tableau de n entiers Rsultat : renvoie la taille du plus long prxe gal au suxe de T Variables : k, i, des entiers, et contient, un boolen. dbut
k n;
et dirent de
T.
tant que k > 0 et non(contient) faire pour tous les i de 1 k faire si T [i] = T [n k + i] alors contient Faux; n
contient
contient
Faux;
k k 1;
Vrai;
n
n renvoyer k;
X 16 en faisant le moins de multiplications possible, l'ide est de le dcomposer en : X = (X ) = ((X 4 )2 )2 = (((X 2 )2 )2 )2 , soit simplement 4 multiplications (en commenant le calcul par 20 l'intrieur des parenthses) ! Si l'exposant n'est pas une puissance de 2, on s'adapte facilement, par exemple 2 10 2 5 2 2 2 2 2 2 se dcompose en : (X ) = ((X ) X ) = (((X ) X ) X ) , soit seulement 6 multiplications ! Dans tous les cas, si k est une puissance de 2, on a besoin de log2 k multiplications (qui sont des lvations i i+1 au carr). Sinon, si k est compris entre 2 et 2 1, on a besoin de i = log2 n lvations au carr, et au plus autant de multiplications par X . Dans tous les cas, au total, il y a (log n) oprations.
calculer rapidement
16
8 2
3.5
Sance 11 (12/11/2008)
div 2);
n
n
sinon renvoyer p p A; n
Algorithme 17 : ExponentiationRapide(A,B
: entiers) : entier
O(n3 ). i et j .
(b) Pour passer une complexit quadratique il sut de mettre jour SomMax quand on fait varier
O(n log n)
somme maximale se trouvera soit dans la premire moiti, soit dans la seconde, soit il empitera sur les deux et
18
Donnes : T [1..n] : un tableau de n entiers relatifs Rsultat : renvoie 0 si tous les lments de T sont ngatifs, la somme maximale des lments, parmi
b
tous ses sous-tableaux sinon, c'est dire
ab[1..n]
max (0,
i=a
T [i]).
pour tous les i de 1 n faire pour tous les j de i n faire n n renvoyer max(0,SomM ax);
somme 0; somme somme + T [j ]; SomM ax max(somme, SomM ax);
n
a donc la somme maximale en partant du milieu dans le sous-tableau gauche, et somme maximale en partant du milieu dans le sous-tableau droit, ce qui permet de le trouver en pour un certain de
O(n).
(d) Pour obtenir un algorithme linaire, et donc optimal, considrons qu'on a les deux invariants proposs
k , et regardons ce qui se passe la case k +1. On appelle Tk le sous-tableau de somme maximale T [1..k ], et Tk le sous-tableau de somme maximale se terminant la case k de T [1..k ]. Ainsi au k -ime pas, SomM ax est la somme des lments de Tk et SomM axDroite est la somme des lments de Tk .
L'algorithme 20 peut tre raccourci pour donner l'algorithme 21 (qui semble un peu trop magique, ce qui explique la prsence de la version longue, qui est en outre plus facile modier pour renvoyer les indices de dbut et de n du tableau de somme maximale).
19
Donnes : T [1..n] : un tableau de n entiers relatifs, d, f Rsultat : renvoie 0 si tous les lments de T
sous-tableau considr tous ses sous-tableaux sinon, c'est dire
b ab[1..n]
max (0,
i=a
T [i]).
Variables : sommeGauche, sommeDroite : deux entiers. dbut si d=f alors renvoyer max(0, T [d]) sinon
sommeGauche 0; somme 0; f pour tous les i de d+ d par pas de -1 faire 2 somme somme + T [i]; sommeGauche max(somme, sommeGauche);
n
sommeDroite 0; somme 0; f pour tous les i de d+ + 1 f faire 2 somme somme + T [i]; sommeDroite max(somme, sommeDroite);
n renvoyer
max
d+f 2
), RecSomMax(T,
d+f 2
+ 1, f )
: entier): entier
20
Donnes : T [1..n] : un tableau de n entiers relatifs, d, f Rsultat : renvoie 0 si tous les lments de T
sous-tableau considr tous ses sous-tableaux sinon, c'est dire
b ab[1..n]
max (0,
i=a
T [i]).
SomM ax T [1]; SomM axDroite T [1]; pour tous les k de 2 n faire si SomM axDroite 0 alors si SomM axDroite + T [k] > SomM ax alors //Le nouveau tableau optimal Tk est Tk1 + SomM ax SomM axDroite + T [k ]; SomM axDroite SomM axDroite + T [k ];
la
k -ime
case :
sinon
n sinon
//SomM axDroite
<0
Tk
est uniquement la
k -ime
case :
sinon n
: entier): entier
Donnes : T [1..n] : un tableau de n entiers relatifs, d, f Rsultat : renvoie 0 si tous les lments de T
sous-tableau considr tous ses sous-tableaux sinon, c'est dire
b ab[1..n]
max (0,
i=a
T [i]).
SomM ax T [1]; SomM axDroite T [1]; pour tous les k de 2 n faire SomM axDroite max(SomM axDroite + T [k ], T [k ]); SomM ax max(SomM axDroite, SomM ax);
: entier): entier
21
Chapitre 4
Listes chanes
4.1
Sance 12 (17/11/2008)
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 22
(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
22
Figure
4.1
Utilisation des listes chanes : aprs la ligne 1 (a), 2 (b), 3 (c), 4 (d), 5 (e),
rorganisation (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).
Quand ce n'est pas prcis dans les exercices sur les listes,
4.2
Sance 13 (19/11/2008)
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 SupprimeValeurD (algorithme 26), en utilisant une liste doublement chane, est linaire. En fait, on peut aussi arriver cette complexit avec une liste simplement chane, en retenant l'adresse de la case prcdente dans une mmoire, ou bien en procdant de manire dcale, et en testant si la contient
case suivante
e,
23
Donnes : L : liste simplement chane Rsultat : renvoie l'adresse de la dernire cellule d'une liste dbut
Variables :
Q,
Q L;
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);
Donnes : L : liste simplement chane, e : entier Rsultat : supprime de L tous les lments de valeur e dbut
Variable :
Q,
Q L; si Q = NULL
24
Donnes : L : liste doublement chane, e : entier Rsultat : supprime de L tous les lments de valeur e dbut
Variable :
Q,
pred succ
succ pred
Q Q
succ ; pred ;
n n n
succ;
Donnes : L : liste simplement chane, e : entier Rsultat : supprime de L tous les lments de valeur e dbut
Variable :
Q,
Q L; si Q = NULL
Q
succ;
succ
succ;
n
25
4.3
Sance 14 (26/11/2008)
Donnes : L : liste simplement chane non vide Rsultat : supprime de L tous les doublons conscutifs dbut
Variable :
Q,
Q L;
tant que Q succ = NULL faire si Q info = Q succ info alors sinon n n
Q
succ
Q
succ;
succ
succ;
n
L1
et
L2
L1
L2 .
Donnes : L1 , L2 : listes simplement chanes Rsultat : modie L1 pour lui concatner L2 dbut
Variable :
Q,
Q L1 ; si Q = NULL L1 L2 ;
alors
L1
L2
Algorithme 29 : Concatene(L1 , L2
est
succ
pred
info. L'intrt est donc de pouvoir accder la case prcdente, ou bien la dernire case, en temps constant. En utilisant des listes doublement chanes, on peut donc eectuer la concatnation en temps constant, avec l'algorithme 30. Il faut juste tre soigneux pour assurer que les bonnes ches pointent au bon endroit. De plus, contrairement la version avec les listes simplement chanes o en version doublement chane, plus vers la table des matires
L2 restait une liste valide aprs concatnation, L2 sera dtruite dans l'opration puisque la dernire case de L2 ne pointera de L2 , mais vers celle de L1 .
26
Donnes : L1 , L2 : listes doublement chanes Rsultat : modie L1 pour lui concatner L2 dbut
// La dernire case de pred
n
L1 pointe vers la premire de L2 : L2 succ; // La premire case de L2 pointe vers la dernire de L1 : L2 succ pred L1 pred; // La dernire case de L2 pointe vers la table des matires L2 pred succ L1 ; // La table des matires de L1 pointe vers la dernire case L1 pred L2 pred; L1
succ
de de
L1 L2
: :
27
Chapitre 5
Arbres
5.1
A trois cases qui reprsente la racine de l'arbre, contient une A info, et un pointeur vers la cellule-racine de son sous-arbre gauche A sag, ainsi qu'un pointeur vers cellule-racine de son sous-arbre droit A sad. Les nuds au bout des branches (nuds de degr 1) d'un
Un arbre binaire est cod comme une cellule Pour parcourir une liste, on pouvait partir de la tte et suivre les pointeurs vers les successeurs jusqu'
arbre binaire sont appels feuilles, ils pointent vers NULL gauche et NULL droite. arriver la n de la liste et donc un pointeur vers NULL l'aide d'une boucle une boucle
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 permet de rsoudre le problme sur 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))
5.2
Sance 15 (03/12/2008)
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 31 : Hauteur(A : arbre binaire) : entier
28
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 32 : NombreFeuilles(A : arbre binaire) : 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
29
Chapitre 6
Tris
|T |
6.1
Sance 16 (10/12/2008)
et
B.
Sans doublons
Dans un premier temps on considrera qu'il n'y a pas de doublons, puis on ajoutera une procdure pour les prendre en compte qui ne changera rien l'ordre de grandeur de la complexit des algorithmes. prsent parmi les
Ide de l'algorithme 34 : pour chacun des |A| lments du premier tableau, on regarde en O(|B |) s'il est
|B |
lments du second tableau (si oui on l'ajoute une liste d'lments de l'intersection des
O(|A||B |).
Donnes : A, B : tableaux d'entiers sans doublons, B est tri. Rsultat : Renvoie le nombre d'entiers prsents dans les deux tableaux.
Variables :
dbut
t,
entier.
n
n
n
Ide de l'algorithme 35 avec un des deux tableaux tri : pour chacun des |A| lments du premier
tableau, on regarde par dichotomie en parmi les lments du second tableau qui sont tris. On obtient donc une complexit en en Si le tableau B n'est pas tri, on peut commencer par le trier en O (|B | log |B |). La complexit totale est donc O(|A| log |B | + |B | log |B |), c'est dire O(max(|A|, |B |) log |B |), elle est meilleure qu'avec l'ide prcdente.
Ide de l'algorithme 36 avec les deux tableaux tris : on parcourt simultanment les deux tableaux
O(|A| + |B |).
Si on considre que les deux tableaux ne sont pas tris, on commence par trier le premier tableau en
O(|A| log |A|), puis le second en O(|B | log |B |), ce qui donne une complexit totale en O(|B | log |B | + |A| log |A| + |A| + |B |), soit O(max(|A|, |B |) log max(|A|, |B |)), ce qui est encore meilleur que l'ide prcdente.
30
Donnes : A, B : tableaux d'entiers sans doublons, B est tri. Rsultat : Renvoie le nombre d'entiers prsents dans les deux tableaux.
Variables :
dbut
t,
entier.
t 0; pour i de 1 |A|
n
Donnes : A, B : tableaux d'entiers sans doublons, A et B sont tris. Rsultat : Renvoie le nombre d'entiers prsents dans les deux tableaux.
Variables :
dbut
t,
entier.
faire
n
n
n
i i + 1; j j + 1; t t + 1;
31
Avec doublons
Pour les deux premiers algorithmes, l'ide est de garder en mmoire dans une variable deux tableaux dj trouve. A chaque fois qu'un lment est trouv la fois dans le tableau
B,
puisque
X . Si non, on l'y ajoute. Cette opration est donc faite |A B | min(|A|, |B |). Quelle structure de donnes utiliser pour X ? Il faut en choisir une qui permet O(log n), O(n) O(log n) recherche en O (nauteur), insertion
insertion en
des oprations de recherche et d'insertion rapide : tableau tri : recherche en tas : recherche en
O(n),
insertion en
en
O(nauteur)
mique en moyenne, mais possiblement linaire). pour avoir des oprations de recherche et d'insertion logarithmique, et donc garder le mme ordre de grandeur de la complexit en
O(|A| log |B |)
Pour le troisime algorithme, c'est plus simple : il sut de poursuivre l'incrmentation des compteurs tant que des lments identiques sont dcouverts, c'est dire insrer juste aprs la ligne
A[i] = A[i 1]
t t + 1;
tant que
et
n lments d'un tableau sont dirents est de tester pour chaque n 1 autres cases. Cet algorithme a une complexit quadratique. On peut trier le tableau en O (n log n) ce qui aura pour eet de rapprocher les doublons
si le tableau en contient. Il sut alors d'utiliser l'algorithme 37 qui parcourt en temps linaire un tableau tri pour vrier qu'il ne contient pas de doublon.
Donnes : T : tableau contenant n entiers tris. Rsultat : Renvoie VRAI si le tableau ne contient que des lments dirents, FAUX sinon
Variables :
dbut
i,
entier.
i 1;
i i + 1;
6.2
Sance 17 (17/12/2008)
k, k
O(k + n).
chire
http://fr.wikipedia.org/wiki/Arbre_AVL http://fr.wikipedia.org/wiki/Arbre_rouge-noir
32
Donnes : T [1..n] : tableau. Rsultat : Renvoie un tableau tri contenant les lments de T dbut si n > 1 alors renvoyer Fusion(T riF usion(T [1.. n/2 ], T [ n/2 + 1..n])); sinon renvoyer T ; n n Algorithme 38 : TriFusion(T : tableau) : tableau
Donnes : T 1, T 2 : tableaux tris. Rsultat : Renvoie un tableau tri contenant les lments de T 1 et T 2
Variables :
dbut
T,
tableau d'entiers
faire
T [i + j 1] T 1[i];
T [i + j 1] T 1[i]; i i + 1; T [i + j 1] T 2[j ]; j j + 1;
n
33
Donnes : T : tableau d'entiers compris entre 0 et 20. Rsultat : Renvoie un tableau tri contenant les lments de T dbut n n
Variables :
N bN otes[1..21], N bN otes
tableau
//Cration de
pour i de 1 21 faire
N bN otes[i] 0;
//Remplissage de
pour i de 1 |T | faire
//Dveloppement de
N bN otes
n
n n renvoyer T ;
Algorithme 40 : TriNotes(T
Donnes : T [1..n] : tableau d'entiers ayant au plus k chires. Rsultat : Renvoie un tableau tri contenant les lments de T
Variables :
dbut n n
F [0..9], k
:
tableau
//Calcul de
pour i de 1 k + 1 faire
//Remplissage du tableau de les tri selon le
pour j de 1 |T | faire n
//Remplissage de
ime
chire :
ajouterFile(F [T [j ][i]], T [j ])
a1
T,
n
n
n
a a + 1;
entiers) : tableau
34