You are on page 1of 104

Algorithmique et

complexit

Mr. Slim Mesfar

Mail: mesfarslim@yahoo.fr
A.U. 2011-2012
Plan du cours
Chap-1: Introduction & motivations
Chap-2: Complexit & optimalit
Chap-3: Algorithmes de tri:
analyse et estimation de la complexit
Chap-4: Rcursivit
Diffrents types de rcursivit
Drcursivation dalgorithmes
Rcursivit terminale et non terminale
Paradigme diviser pour rgner
Chap-5: Graphes et arbres
Chap-6: Arbres binaires de recherche

Objectifs du cours
Elaborer des algorithmes performants et efficaces
Comprendre la notion de complexit dun algorithme
Matriser la rcursivit (simple, multiple, mutuelle,
imbrique)
Savoir drcursiver des algorithmes simples et multiples
Matriser la dmarche diviser pour rgner
Savoir estimer la complexit dun algorithme itratif ou
rcursif pouvant conduire des rcurrences linaires
dordre 1, dordre 2 et des rcurrences de type diviser
rgner
Connatre les diffrents algorithmes de tri et estimer leur
complexit
Elaborer des algorithmes base de graphes et darbres
Raliser des algorithmes de parcours de graphes et darbres

Chapitre 1 Introduction
et motivations
Introduction
Un algorithme = une suite ordonne d'oprations
ou d'instruction crites pour la rsolution d'un
problme donn.
Algorithme = une suite dactions que devra
effectuer un automate pour arriver partir dun
tat initial, en un temps fini, un rsultat

Lalgorithmique dsigne le processus de
recherche dalgorithme
Structures de donnes
Une structure de donnes indique la manire
d'organisation des donnes dans la mmoire.
Le choix d'une structure de donnes adquate
dpend gnralement du problme rsoudre.
Deux types de structures de donnes :
Statiques : Les donnes peuvent tre manipules dans
la mmoire dans un espace statique allou ds le dbut
de rsolution du problme. Ex : les tableaux
Dynamiques : On peut allouer de la mmoire pour y
stocker des donnes au fur et mesure des besoins de
la rsolution du problme. Ex: liste chaine, pile, file,
notion des pointeurs ncessit de la gestion des
liens entre les donnes d'un problme en mmoire.
Qualits dun bon algorithme
Correct: Il faut que le programme excute
correctement les tches pour lesquelles il a t
conu
Complet: Il faut que le programme considre
tous les cas possibles et donne un rsultat dans
chaque cas.
Efficace: Il faut que le programme excute sa
tche avec efficacit cest dire avec un cot
minimal. Le cot pour un ordinateur se mesure
en termes de temps de calcul et despace
mmoire ncessaire.
Exemple : Calcul de la valeur dun polynme
Soit P(X) un polynme de degr n
P(X) = a
n
X
n
+ a
n-1
X
n-1
+ ... + a
1
X + a
0
O,
n : entier naturel
a
n
, a
n-1
, ..., a
1
, a
0
: les coefficients du polynme

1
re
variante :
dbut
P=0
Pour i de 0 n faire
P = P+ a
i
*X
i
finpour
fin
Cot de lalgorithme :
- (n+1) additions
- (n+1) multiplications
- (n+1) puissances
Exemple : Calcul de la valeur dun polynme
2
me
variante :
debut
Inter=1
P =0
Pour i de 0 N faire
P = P+ Inter *a
i
Inter = Inter * X
finpour
Fin
Cot de lalgorithme :
- (n+1) additions
- 2(n+1) multiplications
Exemple : Calcul de la valeur dun polynme
3
me
variante : Schma de Horner

P(x) = (.(((a
n
x+a
n-1
)x+a
n-2
)x+a
n-3
)..)x+a
0

dbut
P = a
n
Pour i de n-1 0 (pas = 1) faire
P = P*X + a
i
finpour
Fin

Ncessit destimer le cot dun algorithme avant de lcrire
et limplmenter
Cot de lalgorithme :
- n additions
- n multiplications
Chapitre 2 Complexit
et optimalit
Dfinitions
la complexit d'un algorithme est la mesure du
nombre d'oprations fondamentales qu'il effectue
sur un jeu de donnes.
La complexit est exprime comme une fonction
de la taille du jeu de donnes.
La complexit d'un algorithme est souvent
dtermine travers une description
mathmatique du comportement de cet
algorithme.
Dfinitions
On note D
n
lensemble des donnes de taille n et T(d) le
cot de lalgorithme sur la donne d.
On dfinit 3 types de complexit :
Complexit au meilleur :
C'est le plus petit nombre d'oprations qu'aura excuter l'algorithme
sur un jeu de donnes de taille fixe, ici n.
Complexit au pire :
C'est le plus grand nombre d'oprations qu'aura excuter
l'algorithme sur un jeu de donnes de taille fixe, ici n.
Complexit en moyenne :
C'est la moyenne des complexits de l'algorithme sur des jeux de
donnes de taille n.
Dfinitions
C'est l'analyse pessimiste ou au pire qui est gnralement
adopte.
En effet, de nombreux algorithmes fonctionnent la plupart
du temps dans la situation la plus mauvaise pour eux.
l'analyse au pire des cas donne une limite suprieure de
la performance et elle garantit qu'un algorithme ne fera
jamais moins bien que ce qu'on a tabli.
Un algorithme est dit optimal si sa complexit est la
complexit minimale parmi les algorithmes de sa classe.
Mme si on sintresse quasi-exclusivement la complexit
en temps des algorithmes. Il est parfois intressant de
sintresser dautres ressources, comme la complexit en
espace (taille de lespace mmoire utilis), la largeur de
bande passante requise, etc.
Notations mathmatiques
La notation O est celle qui est le plus communment
utilise pour expliquer formellement les performances d'un
algorithme.
Cette notation exprime la limite suprieure d'une fonction
dans un facteur constant.

La notation O reflte la courbe ou l'ordre croissance d'un
algorithme.
Les rgles de la notation O sont les suivantes :
Les termes constants : O(c) = O(1)
Les constantes multiplicatives sont omises : O(cT ) = cO(T) = O(T)
L'addition est ralise en prenant le maximum : O(T1) + O(T2) =
O(T1 + T2) = max(O(T1);O(T2))
La multiplication reste inchange mais est parfois rcrite d'une faon
plus compacte :O(T1)O(T2) = O(T1T2)
Exemple
On suppose quon dispose d'un algorithme dont le temps
d'excution est dcrit par la fonction T(n) = 3n
2
+10n+10.
L'utilisation des rgles de la notation O nous permet de
simplifier en :
O(T(n)) = O(3n
2
+ 10n + 10) = O(3n
2
) = O(n
2
)
Pour n = 10 nous avons :
Temps d'excution de 3n
2
: 3(10)
2
/ 3(10)
2
+10(10)+10 = 73,2%
Temps d'excution de 10n : 10(10) / 3(10)
2
+10(10)+10 = 24,4%
Temps d'excution de 10 : 10 / 3(10)
2
+10(10)+10 = 2,4%
Le poids de 3n
2
devient encore plus grand quand n = 100,
soit 96,7% on peut ngliger les quantits 10n et 10.
Ceci explique les rgles de la notation O.
Classes de complexit
Les algorithmes usuels peuvent tre classs en un certain
nombre de grandes classes de complexit.
Les complexits les plus utilises sont :
Constante : O( 1) Accder au premier lment d'un ensemble de
donnes
Logarithmique : O( logn) Couper un ensemble de donnes en deux
parties gales, puis couper ces moitis en deux parties gales, etc.
Linaire : O( n) Parcourir un ensemble de donnes
Quasi- linaire : O( nlogn) Couper rptitivement un ensemble de
donnes en deux et combiner les solutions partielles pour calculer la
solution gnrale
Quadratique : O( n
2
) Parcourir un ensemble de donnes en utilisant
deux boucles imbriques
Polynomiale : O( n
P
) Parcourir un ensemble de donnes en utilisant
P boucles imbriques
Exponentielle : O( 2
n
) Gnrer tous les sous-ensembles possibles
d'un ensemble de donnes
Classes de complexit

Calcul de la complexit
1. Cas d'une instruction simple : criture, lecture,
affectation
Dans le cas d'uns suite d'instructions simples, on considre la
complexit maximale.






La complexit de cette squence vaut max(O(1),O(1))=O(1).
Calcul de la complexit
2. Cas d'un traitement conditionnel






3. Cas d'un traitement itratif : Boucle Tant Que


Calcul de la complexit
4. Cas d'un traitement itratif : Boucle Pour









Pour i de indDeb indFin faire
Traitement
Fin Pour



=
indFin
indDeb i
Traitement
T O ) (
Exemples de calcul de la complexit
Exemple 1 : Tri par insertion
Principe : Cette mthode de tri s'apparente
celle utilise pour trier ses cartes dans un jeu :
on prend une carte, tab[1], puis la deuxime,
tab[2], que l'on place en fonction de la
premire, ensuite la troisime tab[3] que l'on
insre sa place en fonction des deux
premires et ainsi de suite. Le principe gnral
est donc de considrer que les (i-1) premires
cartes, tab[1],..., tab[i-1] sont tries et de
placer la i
e
carte, tab[i], sa place parmi les
(i-1) dj tries, et ce jusqu' ce que i = N.

Exemples de calcul de la complexit
Exemple 1 : Tri par insertion
Procdure tri_Insertion (var tab : tableau entier [N])
i, k :entier ;
tmp : entier ;
Pour i de 2 N faire
tmp tab[i];
k i;
Tant que k > 1 ET tab[k - 1] > tmp faire
tab[k] tab[k - 1];
k k - 1;
Fin Tant que
tab[k] tmp;
Fin pour
Fin
Exemples de calcul de la complexit
Exemple 1 : Tri par insertion
Calcul de la complexit:
la taille du tableau trier est n.
On a deux boucles imbriques :
La premire indique l'lment suivant insrer dans
la partie trie du tableau.
Elle effectuera n - 1 itrations puisque le premier
lment est dj tri.
Pour chaque lment donn par la premire boucle,
on fait un parcourt dans la partie trie pour
dterminer son emplacement.
Exemples de calcul de la complexit
Exemple 1 : Tri par insertion
Calcul de la complexit:
Au meilleur des cas : le cas le plus favorable
pour cet algorithme est quand le tableau est
dj tri (de taille n) O(n)
Au pire des cas : Le cas le plus dfavorable
pour cet algorithme est quand le tableau est
inversement tri on fera une itration pour
le 1
er
lment, deux itrations pour le 2
me
et
ainsi de suite pour les autres lments.
Soit 1+2+3+4++(n-1) =
sa complexit O(n
2
)
n
n n

+
2
) 1 (
Exemples de calcul de la complexit
Exemple 1 : Tri par insertion
Calcul de la complexit:
En moyenne des cas : En moyenne, la moiti
des lments du tableau sont tris, et sur
lautre moiti ils sont inversement tris.
O(n
2
)
Exemples de calcul de la complexit
Exemple 2 : Recherche dichotomique
Fonction RechDicho(Tab :Tableau, borneinf :entier, bornesup :entier,
elemcherche :entier) : entier
Trouve = false ;
Tant que ((non trouve) ET (borneinf<=bornesup)) faire
mil = (borneinf+bornesup) DIV 2 ;
Si (Tab[mil]=elemcherche) Alors
trouve=true ;
Sinon
Si (elemcherche < Tab[mil]) Alors bornesup = mil-1 ;
Sinon borneinf = mil+1 ;
Fin Si
Fin Si
Fin Tant que
Si (trouve) Alors Retourner (mil) ;
Sinon Retourner (-1) ;
Fin Si
Fin
Exemples de calcul de la complexit
Exemple 2 : Recherche dichotomique
Cette fonction effectue une recherche dichotomique d'un
lment dans un tableau tri. Supposons que le tableau est
de taille n une puissance de 2 (n = 2
q
).
Le pire des cas pour la recherche d'un lment est de
continuer les divisions jusqu' obtenir un tableau de taille 1.
q le nombre d'itrations ncessaires pour aboutir un
tableau de taille 1
dernire itration taille tableau = 1
La complexit = log
2
(n)
Chapitre 3
Les algorithmes de Tri
Tri par slection
Principe :
Le principe est que pour classer n valeurs,
il faut rechercher la plus petite valeur
(resp. la plus grande) et la placer au
dbut du tableau (resp. la fin du
tableau), puis la plus petite (resp. plus
grande) valeur dans les valeurs restantes
et la placer la deuxime position (resp.
en avant dernire position) et ainsi de
suite...

Tri par slection
Algorithme :
i, j: entier ;
tmp, small : entier ;
t : tableau entier [n] ;
Dbut
Pour i de 1 n-1 faire
smalli;
Pour j de i+1 n faire
Si t[j] < t[small] alors
small j ;
Fin si
Fin pour
tmpt[small];
t[small] t[i];
t[i] tmp;
Fin pour
Fin
T(n) = O(n)
Tri par propagation / bulles
Principe :
Il consiste parcourir le tableau tab en permutant
toute paire d'lments conscutifs
(tab[k],tab[k+1]) non ordonns - ce qui est un
change et ncessite donc encore une variable
intermdiaire de type entier. Aprs le premier
parcours, le plus grand lment se retrouve dans
la dernire case du tableau, en tab[N], et il reste
donc appliquer la mme procdure sur le tableau
compos des lments tab[1], ..., tab[N-1].

Tri par propagation / bulles
Algorithme :
Procdure tri_Bulle (tab : tableau entier [N] ) i,
k :entier ;tmp : entier ;
Pour i de N 2 faire
Pour k de 1 i-1 faire
Si (tab[k] > tab[k+1]) alors
tmp tab[k];
tab[k] tab[k+1];
tab[k+1] tmp;
Fin si
Fin pour
Fin pour
Fin
T(n) = O(n)
Chapitre 4 La rcursivit
Dfinitions
Un algorithme est dit rcursif s'il est dfini en
fonction de lui-mme.
La rcursion est un principe puissant permettant de
dfinir une entit l'aide d'une partie de celle-ci.
Chaque appel successif travaille sur un ensemble
d'entres toujours plus affine, en se rapprochant
de plus en plus de la solution d'un problme.
Evolution dun appel rcursif
L'excution d'un appel rcursif passe par deux
phases, la phase de descente et la phase de la
remonte :
Dans la phase de descente, chaque appel rcursif fait
son tour un appel rcursif. Cette phase se termine
lorsque l'un des appels atteint une condition terminale.
condition pour laquelle la fonction doit retourner une
valeur au lieu de faire un autre appel rcursif.
Ensuite, on commence la phase de la remonte. Cette
phase se poursuit jusqu' ce que l'appel initial soit
termin, ce qui termine le processus rcursif.
Les types de rcursivit
1/ La rcursivit simple :
rcursivit simple la fonction contient un seul appel
rcursif dans son corps.
Exemple : la fonction factorielle
Les types de rcursivit
Trace dexcution de la fonction factorielle (calcul de la
valeur de 4!)
Les types de rcursivit
2/ La rcursivit multiple:
rcursivit multiple la fonction contient plus d'un
appel rcursif dans son corps
Exemple : le calcul du nombre de combinaisons en se
servant de la relation de Pascal :

Les types de rcursivit
3/ La rcursivit mutuelle:
Des fonctions sont dites mutuellement rcursives si elles
dpendent les unes des autres
Par exemple la dfinition de la parit d'un entier peut
tre crite de la manire suivante :
Les types de rcursivit
4/ La rcursivit imbrique:
Exemple : La fonction d'Ackermann
Rcursivit terminale vs. non terminale
Une fonction rcursive est dite rcursive
terminale si tous ses appels sont rcursifs
terminaux.
Un appel rcursif est terminal s'il s'agit de la
dernire instruction excute dans le corps d'une
fonction et que sa valeur de retour ne fait pas
partie d'une expression.
Les fonctions rcursives terminales sont
caractrises par le fait qu'elles n'ont rien faire
pendant la phase de remonte
Importance de lordre des appels rcursifs
Proc. terminale
Procdure AfficherGaucheDroite (
Tab : Tableau entier, N : entier,
i : entier)
Si (i<=N) Alors
Ecrire(Tab[i]) ;
AfficherGaucheDroite (Tab,N,i+1) ;
Fin Si
Fin
Proc. non terminale
Procdure AfficherDroiteGauche (
Tab : Tableau entier, N : entier,
i : entier)
Si (i<=N) Alors
AfficherDroiteGauche (Tab,N,i+1) ;
Ecrire(Tab[i]) ;
Fin Si
Fin
lordre des appels rcursifs affecte la terminaison dune
fonction rcursive
Importance de lordre des appels rcursifs
Elimination de la rcursivit
Drcursiver, cest transformer un
algorithme rcursif en un algorithme
quivalent ne contenant pas des appels
rcursifs.
Elimination de la rcursivit terminale
simple
Rappel : Un algorithme est dit rcursif terminal
sil ne contient aucun traitement aprs un appel
rcursif.
La rcursivit terminale simple peut tre
remplace par une solution itrative.
Elimination de la rcursivit terminale
simple
Algo. rcursif
Procdure ALGOR(X)
Si (COND) Alors
TRAIT1
ALGOR( ( X) )
Sinon
TRAIT2
Fin Si
Fin
Algo. itratif
Procdure ALGOI(X)
Tant que (COND) faire
TRAIT1
X ( X)
Fin tant que
TRAIT2
Fin
X est la liste des paramtres ;
COND est une condition portant sur X ;
TRAIT1 est le traitement de base de l'algorithme (dpendant de X) ;
(X) reprsente la transformation des paramtres ;
TRAIT2 est le traitement de terminaison (dpendant de X).
Application : a est diviseur de b ?
Algo. rcursif
Fonction Diviseur (a,b) : Bool
Si (a <=0) Alors
Retourner(Faux)
Sinon
Si (a>=b) Retourner (a=b)
Sinon
Retourner (Diviseur (a,b-a))
Fin Si
Fin Si
Fin
Algo. itratif
Fonction Diviseur (a,b) : Bool
Si (a <=0) Alors
Retourner(Faux)
Sinon
Tant que (a<b) Faire
b b-a
Fin tant que
Retourner (a=b)
Fin Si
Fin

Elimination de la rcursivit non
terminale simple
Dans un algorithme rcursif non terminal, lappel
rcursif est suivi dun traitement il reste un
traitement reprendre aprs lappel rcursif
Il va falloir donc sauvegarder, sur une pile, le
contexte de lappel rcursif, typiquement les
paramtres de lappel engendrant lappel rcursif.
La rcursivit non terminale simple peut tre
remplace par une solution itrative utilisant une
pile.

Elimination de la rcursivit non terminale
simple
Algo. rcursif
Procdure ALGOR(X)
Si (COND) Alors
TRAIT1
ALGOR( ( X) )
TRAIT2
Sinon
TRAIT3
Fin Si
Fin
Algo. itratif
Procdure ALGOI(X)
Pile.init()
Tant que (COND) Faire
TRAIT1
Pile.empiler(X)
X ( X)
Fin Tant que
TRAIT3
Tant que (Non_vide_pile())
Faire
Pile.dpiler(U)
TRAIT2
Fin Tant que
Fin
Elimination de la rcursivit non terminale
simple
Algo. rcursif
Procdure
AfficherDroiteGauche ( Tab
: Tableau entier, N :
entier, i : entier)
Si (i<=N) Alors
AfficherDroiteGauche
(Tab,N,i+1) ;
Ecrire(Tab[i]) ;
Fin Si
Fin
TRAIT1 =
TRAIT2 = Ecrire(Tab[i])
TRAIT3 =
Algo. itratif
Procdure ALGOI(X)
Pile.init()
Tant que (i<=N) Faire
/* TRAIT1 */
Pile.empiler(Tab[i])
i i+1
Fin Tant que
/* TRAIT3 */
Tant que (Non_vide_pile())
Faire
Ecrire(Pile.dpiler() )
/* TRAIT2 */
Fin Tant que
Fin
Exemple : Tours de Hanoi
Problme :
Le jeu est constitu dune plaquette de bois o
sont plantes trois tiges numrotes 1, 2 et 3.
Sur ces tiges sont empils des disques de
diamtres tous diffrents. Les seules rgles du
jeu sont que lon ne peut dplacer quun seul
disque la fois, et quil est interdit de poser un
disque sur un disque plus petit.
Au dbut, tous les disques sont sur la tige 1
(celle de gauche), et la fin ils doivent tre sur
celle de droite.
Exemple : Tours de Hanoi
Rsolution:
On suppose que lon sait
rsoudre le problme pour (n-1)
disques. Pour dplacer n disques
de la tige 1 vers la tige 3, on
dplace les (n-1) plus petits
disques de la tige 1 vers la tige
2, puis on dplace le plus gros
disque de la tige 1 vers la tige 3,
puis on dplace les (n-1) plus
petits disques de la tige 2 vers la
tige 3.
Exemple : Tours de Hanoi
Algorithme
Procdure Hanoi (n, dpart, intermdiaire, destination)
Si n > 0 Alors
Hanoi (n-1, dpart, destination, intermdiaire)
dplacer un disque de dpart vers destination
Hanoi (n-1, intermdiaire, dpart, destination)
Fin Si
Fin
Exemple : Tours de Hanoi
Trace dexcution pour n=3
Lappel Hanoi(3,1,2,3) entrane laffichage de :
1. Dplace un disque de la tige 1 vers la tige 3
2. Dplace un disque de la tige 1 vers la tige 2
3. Dplace un disque de la tige 3 vers la tige 2
4. Dplace un disque de la tige 1 vers la tige 3
5. Dplace un disque de la tige 2 vers la tige 1
6. Dplace un disque de la tige 2 vers la tige 3
7. Dplace un disque de la tige 1 vers la tige 3
Exemple : Tours de Hanoi
Calcul de la complexit :
On compte le nombre de dplacements de
disques effectus par lalgorithme Hanoi
invoqu sur n disques.
On trouve :
T(n) = T(n-1) + 1 + T(n-1)
T(n) = 2T(n-1) + 1
T(n) = 2
n
1
Complexit exponentielle


Paradigme diviser pour rgner
De nombreux algorithmes ont une structure rcursive: pour
rsoudre un problme donn, ils sappellent eux-mmes
rcursivement une ou plusieurs fois sur des problmes trs
similaires, mais de tailles moindres, rsolvent les sous
problmes de manire rcursive puis combinent les
rsultats pour trouver une solution au problme initial.
Le paradigme diviser pour rgner parcourt trois
tapes chaque appel rcursif savoir :
Diviser : le problme en un certain nombre de sous-
problmes de taille moindre ;
Rgner : sur les sous-problmes en les rsolvant d'une faon
rcursive ou le rsoudre directement si la taille d'un sous-
problme est assez rduite ;
Combiner : les solutions des sous-problmes en une solution
globale pour le problme initial.
Exemple 1
Recherche de lindice du maximum dans un tableau dentiers
Fonction maximum ( Tab , indDeb, indFin)
Si ( indDeb = indFin) alors
retourner (indDeb)
Sinon
m=(indDeb+indFin)/2 // division du problme en 2 sous-problmes
k1 = maximum (Tab, indDeb, m ) // rgner sur le 1er sous-problme
k2 = maximum (Tab, m+1, indFin)// rgner sur le 2me sous-problme
Si(Tab[k1] > Tab[k2]) Alors // combiner les solutions
retourner (k1)
Sinon
retourner (k2)
FinSi
FinSi
Fin
T(n) = 2 T(n/2) + cte
Exemple2 : multiplication de matrices carres
Dans cet exemple, on se propose de multiplier 2
matrices carres A et B de taille n * n chacune,
o n est une puissance exacte de 2. C est la
matrice rsultante.
Si on dcompose les matrices A, B et C en sous-
matrices de taille n/2 * n/2, l'quation C = AB
peut alors se rcrire :


Le dveloppement de cette quation donne :
r = ae+bf ; s = ag+bh; t = ce+df et u = cg+dh
Exemple2 : multiplication de matrices carres
Chacune de ces quatre oprations correspond :
deux multiplications de matrices carres de taille n/2
2T(n/2)
et une addition de telles matrices n
2
/4
A partir de ces quations on peut driver un
algorithme diviser pour rgner dont la
complexit est donne par la rcurrence :
T(n) = 8T(n/2)+O(n2)

Analyse des algorithmes Diviser pour Rgner
On peut souvent donner une relation de rcurrence qui dcrit
le temps d'excution dun algorithme diviser pour rgner
en fonction des temps d'excution des appels rcursifs
rsolvant les sous-problmes associs de taille moindre.
Cette rcurrence se dcompose suivant les trois tapes du
paradigme de base :
Si la taille du problme est suffisamment rduite, n c pour
une certaine constante c, la rsolution est directe et consomme
un temps constant O(1).
Sinon, on divise le problme en a sous-problmes chacun de
taille 1/ b de la taille du problme initial. Le temps d'excution
total se dcompose alors en trois parties :
D(n) : le temps ncessaire la division du problme en sous-
problmes.
aT (n/b) : le temps de rsolution des a sous-problmes.
C(n) : le temps ncessaire pour construire la solution finale partir
des solutions aux sous-problmes.
Analyse des algorithmes Diviser pour Rgner
La relation de rcurrence prend alors la forme :



Soit la fonction f (n) la fonction qui regroupe D(n)
et C(n). La fonction T(n) est alors dfinie :
T(n) = a.T(n / b) + f (n)
T (n) = a.T (n / b) + c.n
k

Rsolution des rcurrence des algorithmes
Diviser pour Rgner
Thorme de rsolution de la rcurrence :
si a > b
k
T(n) = O(n
log
b
a
)
si a = b
k
T(n) = O(n
k
log
b
n)
si a < b
k
T(n) = O( f (n)) = O(n
k
)
Rsolution de la relation de rcurrence pour
lexemple de la multiplication de matrices :
T(n) = 8 T(n/2) + O(n
2
)
a = 8 , b = 2, k = 2 a > b
k

Log
b
a = 3
T(n) = O(n
3
)
Analyse des algorithmes Diviser pour Rgner
Complexit de lalgorithme de recherche du
maximum: T(n) = 2 T(n/2) + 3
a = 2 , b = 2, k = 0 a > b
k

Log
b
a = 1
T(n) = O(n)
Application : algorithme de recherche dichotomique
Fonction RechDicho(Tab :Tableau, borneinf :entier, bornesup :entier,
elem :entier) : bool

Si (borneinf<=bornesup) alors
mil = (borneinf+bornesup) DIV 2 ;
Si (Tab[mil]=elem) Alors
retourner (vrai)
Sinon
Si (Tab[mil]>elem) Alors
Retourner (RechDicho(Tab, borneinf, mil-1, elem))
Sinon
Retourner(RechDicho(Tab, mil+1, bornesup, elem))
Fin Si
Fin Si
Sinon
Retourner (Faux)
FinSi

Application : algorithme de recherche dichotomique
Analyse de la complexit :
T(n) = T(n/2) + cte
a = 1 , b = 2, k = 0 a = b
k

a = b
k
T(n) = O(n
k
log
b
n)
T(n) = O(log
2
n)


Exemples dapplication
Exemple 1 :
a = 9 , b = 3 , k = 1
a > b
k

Log
b
a = 2
T(n) = O(n)
Exemple 2 :
a = 1 , b = 3/2 , k = 0
a = b
k

T(n) = O(n
k
logn) = O(logn)



n
n
T n T +

=
3
9 ) (
1
3
2
) ( +

=
n
T n T
Exemples dapplication
Exemple 3 :
a = 3 , b = 4 , k = ??
or n < nlogn < n 1 < k < 2
4 < b
k
< 16 a < b
k

T(n) = O(f(n)) = O(n logn)



n n
n
T n T log
4
3 ) ( +

=
Autres rsolutions de rcurrence
Equations de rcurrence linaires:


Exemple : Les Tours de Hanoi
T(n) = 2 T(n-1) + 1


( ) ( ) n f n aT n T + = 1 ) (

+ =

=
n
i
i
n
a
i f
T a n T
1
) (
) 0 ( ) (
1 2
2
1
0 2 ) (
1
=

+ =

=
n
n
i
i
n
n T
Autres rsolutions de rcurrence
Equations de rcurrence linaires sans second
membre (f(n) = cte)

A une telle quation, on peut associer un
polynme:
La rsolution de ce polynme nous donne m
racines r
i
( avec m<=k).
La solution de lquation de rcurrence est ainsi
donne par :

Cette solution est en gnral exponentielle
( ) ( ) ( ) cte k n T a n T a n T a n T
k
= ... 2 1 ) (
2 1
k
k k k
a x a x a x x P =

... ) (
2
2
1
1
n
m m
n n n
r c r c r c r c n T + + + + = ... ) (
3 3 2 2 1 1
Autres rsolutions de rcurrence
Exemple : La suite de Fibonacci


T(n) = T(n-1) + T(n-2)
On pose P(x) = X - X 1






2
5 1
2
5 1
2 1

=
+
= r et r
n n
n n
b a r b r a n T

+
= + =
2
5 1
2
5 1
) (
2 1

+
=
n
n T
2
5 1
) (
Suite du chapitre 3
Les algorithmes de Tri
Tri par fusion
Principe :
Le principe du tri par fusion est plutt
simple. On dit que trier un tableau de
taille N, c'est trier deux tableaux de taille
N/2; une fois les deux tableaux tris on
na plus qu' les runir (les fusionner) de
sorte ce que le tableau final soit tri. Ce
tri bien sr utilise une notion de
rcursivit (un tableau tant la somme de
deux tableaux).

Tri par fusion
Algorithme :
Fonction tri_fusion (T, deb, fin) : tableau entier
T1, T2 : tableau entier [N/2] ;
Si (deb >= fin) alors
Retourner T ;
Sinon
mil = (deb + fin) DIV 2;
T1 = tri_fusion (T, deb, mil) ;
T2 = tri_fusion (T, mil+1, fin)) ;
Retourner fusion (T1, T2) ;
Fin si
FIN
T(n) = 2 T(n/2) + T
fusion
(n)
Tri par fusion
Fonction fusion (T1, T2) : tableau entier
T1 : tableau entier [1...N] ; T2 : tableau entier [1...M] ;
T: tableau entier [1...M+N] ;
i, j: entier; i1 ;j1 ;
Tantque (i+j-1 <> N+M) faire
Si (i N) alors
si (j M) alors
si (T1[i] < T2[j]) alors
T[i+j-1]T1[i] ; ii+1 ;

sinon
T[i+j-1]T2[j] ; jj+1 ;
Fin si
sinon
T[i+j-1]T1[i]; ii+1;
Fin si
sinon T[i+j-1]T2[j] ;
jj+1 ; Fin si
FinTanque Retourner T ;FIN T
fusion
(n) = O(n)
Tri par fusion
Lalgorithme Tri_Fusion est de type diviser pour
rgner . Il faut donc tudier ses trois phases:
Diviser : cette tape se rduit au calcul du milieu
de lintervalle [deb,fin], sa complexit est donc
en O(1).
Rgner : lalgorithme rsout rcursivement deux
sous-problmes de tailles respectives (n/2) , do
une complexit en 2T(n/2).
Combiner : la complexit de cette tape est celle
de lalgorithme de fusion qui est de O(n) pour la
construction dun tableau solution de taille n.
Tri par fusion
T(n) = 2 T(n/2) + O(n)
Rappel : Thorme de rsolution de la rcurrence
T(n) = a T(n/b) + O(n
k
):
si a > b
k
T(n) = O(n
log
b
a
)
si a = b
k
T(n) = O(n
k
log
b
n)
si a < b
k
T(n) = O( f (n)) = O(n
k
)
a = 2, b = 2, k = 1 (2
me
cas)
T(n) = O(n log
2
n)

Tri rapide (Quicksort)
Principe :
Le tri rapide est fond sur le paradigme diviser pour
rgner, tout comme le tri par fusion, il se dcompose donc
en trois tapes :
Diviser : Le tableau T[deb..fin] est partitionn (et
rarrang) en deux sous-tableaux non vides, T[deb..inter] et
T[inter+1..fin] tels que chaque lment de T[deb..fin] soit
infrieur ou gal chaque lment de T[inter+1..fin].
Lindice inter est calcul pendant la procdure de
partitionnement.
Rgner : Les deux sous-tableaux T[deb..inter] et
T[inter+1..fin] sont tris par des appels rcursifs.
Combiner : Comme les sous-tableaux sont tris sur place,
aucun travail nest ncessaire pour les recombiner, le tableau
T[deb..fin] est dj tri !
Tri rapide
Tri_Rapide (T, deb, fin)
Si (deb < fin ) alors
inter =Partionner (T, deb, fin)
Tri_Rapide (T, deb, inter)
Tri_Rapide (T, inter+1, fin)
Fin si
Partionner (T, deb, fin)
x = T(deb)
i = deb-1 ; j= fin+1
Tant que (1)
Rpter { j=j-1 } Jusqu T(j) <= x
Rpter { i =i+1 } Jusqu T(i) >= x
si ( i < j )
permuter (T(i), T(j))
sinon retourner j Fin Si
Fin
Tri rapide : calcul de la complexit
Pire cas
Le cas pire intervient quand le partitionnement produit une rgion
n-1 lments et une 1 lment.
Comme le partitionnement cote O(n) et que T(1) = O(1), la
rcurrence pour le temps dexcution est : T(n) = T(n-1) +O(n)
et par sommation on obtient : T(n) = O(n)
Meilleur cas :
Le meilleur cas intervient quand le partitionnement produit deux
rgions de longueur n/2.
La rcurrence est alors dfinie par : T(n) = 2T(n / 2) + O(n)
ce qui donne daprs le thorme de rsolution des rcurrences :
T(n) = O(nlog n)

Chapitre 5
Graphes et arbres
Les graphes
Un graphe orient G est reprsent par un couple
(S, A) o S est un ensemble fini et A une relation
binaire sur S. Lensemble S est lensemble des
sommets de G et A est lensemble des arcs de G.
Il existe deux types de graphes :
graphe orient : les relations sont orientes et on parle darc. Un
arc est reprsent par un couple de sommets ordonns.
Graphe non orient : les relations ne sont pas orientes et on
parle alors dartes.
Une arte est reprsente par une paire de sommets non
ordonns.
Les graphes
Une boucle est un arc qui relie un sommet lui-mme. Dans un
graphe non orient les boucles sont interdites et chaque arte est
donc constitue de deux sommets distincts.
Degr dun sommet : Dans un graphe non orient, le degr dun
sommet est le nombre dartes qui lui sont incidentes. Si un
sommet est de degr 0, il est dit isol.
Degr sortant dun sommet : Dans un graphe orient, le degr
sortant dun sommet est le nombre darcs qui en partent,
Degr rentrant dun sommet : le degr entrant est le nombre
darcs qui y arrivent et le degr est la somme du degr entrant et
du degr sortant.
Chemin : Dans un graphe orient G = (S,A), un chemin de
longueur k dun sommet u un sommet v est une squence
(u
0
,u
1
,, u
k
) de sommets telle que u = u
0
, v = u
k
et (u
i-1
, u
i
)
appartient A pour tout i.
Un chemin est lmentaire si ses sommets sont tous distincts
Les graphes
Un sous-chemin p
0
dun chemin p = (u
0
,u
1
, . ,u
k
) est une sous-
squence contigu de ses sommets. Autrement dit, il existe i et j,
0<=i<= j <=k, tels que p0 = (u
i
,u
i+1
, . ,u
j
).
Circuit : Dans un graphe orient G=(S,A), un chemin (u
0
,u
1
, .
,u
k
) forme un circuit si u
0
=u
k
et si le chemin contient au moins un
arc. Ce circuit est lmentaire si les sommets u
0
, ..., u
k
sont
distincts. Une boucle est un circuit de longueur 1.
Cycle : Dans un graphe non orient G = (S,A), une chane
(u
0
,u
1
,., u
k
) forme un cycle si k >= 2 et si u
0
= u
k
. Ce cycle est
lmentaire si les sommets u
0
, ..., u
k
sont distincts. Un graphe
sans cycle est dit acyclique.
Sous-graphe : On dit quun graphe G0 = (S0,A0) est un sous-
graphe de G = (S,A) si S0 est inclus dans S et si A0 est inclus
dans A.
Les arbres
Proprits des arbres :
Soit G = (S,A) un graphe non orient. Les affirmations
suivantes sont quivalentes.
1. G est un arbre.
2. Deux sommets quelconques de G sont relis par un unique
chemin lmentaire.
3. G est acyclique et |A| = |S| - 1
4. G est acyclique, mais si une arte quelconque est ajoute
A, le graphe rsultant contient un cycle.
Arbres dfinitions
Arbre enracin (ou arborescence): Cest un arbre dans
lequel lun des sommets se distingue des autres. On appelle
ce sommet la racine. Ce sommet particulier impose en
ralit un sens de parcours de larbre
Anctre : Soit x un noeud (ou sommet) dun arbre A de
racine r. Un noeud quelconque y sur lunique chemin allant
de r x est appel anctre de x.
Pre et fils : Si (y,x) est un arc alors y est le pre de x et
x est le fils de y. La racine est le seul noeud qui na pas de
pre.
Feuille ou noeud externe (ou terminal) : Une feuille est
un noeud sans fils. Un noeud qui nest pas une feuille est
un noeud interne.
Sous-arbre : Le sous-arbre de racine x est larbre compos
des descendants de x, enracin en x.
Arbres - dfinitions
Degr dun nud : Le nombre de fils du nud x est
appel le degr de x.
Profondeur dun nud : La longueur du chemin entre la
racine r et le nud x est la profondeur de x.
Profondeur de larbre : cest la plus grande profondeur
que peut avoir un nud quelconque de larbre. Elle est dite
aussi la hauteur de larbre.
Arbre binaire : cest un arbre dont chaque nud a au plus
deux fils.
Arbre binaire complet : Dans un arbre binaire complet
chaque nud est soit une feuille, soit de degr deux. Aucun
nud nest donc de degr 1.
Parcours des arbres
Parcours en profondeur
Dans un parcours en profondeur, on descend dabord le
plus profondment possible dans larbre puis, une fois
quune feuille a t atteinte, on remonte pour explorer les
autres branches en commenant par la branche la plus
basse parmi celles non encore parcourues. Les fils dun
nud sont bien videmment parcourus suivant lordre sur
larbre.
Algorithme:
Algorithme ParPro(A)
si A nest pas rduit une feuille alors
Pour tous les fils u de racine(A) Faire
ParPro(u)
Fin pour
finSi
Fin
Parcours des arbres
Parcours en largeur
Dans un parcours en largeur, tous les nuds une
profondeur i doivent avoir t visits avant que le premier
nud la profondeur i+1 ne soit visit. Un tel parcours
ncessite lutilisation dune file dattente pour se souvenir
des branches qui restent visiter.
Algorithme:
Algorithme Parcours_Largeur(A)
F : File dattente
F.enfiler(racine(A))
Tant que F != vide Faire
u=F.dfiler()
Afficher (u)
Pour chaque fils v de u Faire
F.enfiler (v)
FinPour
Fin Tant que
Fin
Parcours des graphes
Le parcours des graphes est un peu plus compliqu que
celui des arbres. En effet, les graphes peuvent contenir des
cycles et il faut viter de parcourir indfiniment ces cycles.
Pour cela, il suffit de colorier les sommets du graphe.
Initialement les sommets sont tous blancs,
lorsquun sommet est rencontr pour la premire fois il est
peint en gris,
lorsque tous ses successeurs dans lordre de parcours ont t
visits, il est repeint en noir.
Parcours des graphes
Algorithme Pacours_Profondeur (G)
Pour chaque sommet u de G Faire
couleur[u]=Blanc
FinPour
Pour chaque sommet u de G Faire
si couleur[u] = Blanc alors
VisiterPP(G, u)
FinSi
FinPour
Fin
Algorithme VisiterPP(G, s)
couleur[s]=Gris
Pour chaque voisin v de s Faire
Si couleur[v] = Blanc alors
VisiterPP(G, v)
FinSi
FinPour
couleur[s]=Noir

Fin

Parcours des graphes
Algorithme Parcours_Largeur(G, s)
F : File dattente
Pour chaque sommet u de G Faire
couleur[u] = Blanc
FinPour
couleur[s]=Gris
F.enfiler(s)
Tant que F != Vide Faire
u=F.dfiler()
Pour chaque voisin v de u Faire
Si couleur(v) = Blanc alors
couleur(v)= Gris
F.enfiler(v)
FinPour
Couleur(u)= Noir
FinTant que
Fin
Chapitre 6
Arbres binaires de
recherche
Dfinitions
Un arbre binaire est un graphe qui admet une racine et
sans cycle et dont chaque nud admet deux fils : fils droit
et fils gauche.
Structure de donnes :
Enregistrement Nud
{
Info : Type (entier, rel, chaine, )
FilsG : ^ Nud
FilsD : ^ Nud
}
Racine : ^Nud
Il existe 3 mthodes de parcours dun arbre binaire :
parcours prfixe : pre, fils gauche, fils droit
parcours infixe : fils gauche, pre, fils droit
parcours postfixe : fils gauche, fils droit, pre
Parcours prfix
Algorithme Prfixe(racine : ^Nud)

Si (racine != Nil) Alors
AfficheRacine(racine)
Prfixe (racine^.FilsG)
Prfixe (racine^.FilsD)
FinSi
Fin
Parcours prfix utilisant une pile
Le programme suivant est une version drcursive
utilisant une pile explicite et permettant le parcours prfix
dun arbre binaire.
Algorithme Prfixe (racine : ^Nud)
P : pile
Empiler (P, racine)
Tant que (Non_Vide(P))
racine = depiler (P)
Empiler (P,racine^.FilsD)
Empiler (P,racine^.FilsG)
Fin Tant que
Fin

Parcours infix
Algorithme infixe(racine : ^Nud)

Si (racine != Nil) Alors
infixe (racine^.FilsG)
AfficheRacine(racine)
infixe (racine^.FilsD)
FinSi
Fin
Parcours postfix
Algorithme Postfixe(racine : ^Nud)

Si (racine != Nil) Alors
Postfixe (racine^.FilsG)
Postfixe (racine^.FilsD)
AfficheRacine(racine)
FinSi
Fin
Arbre binaire de recherche
Un arbre binaire de recherche est un arbre binaire dans
lequel chaque nud est suprieur son fils gauche et
infrieur son fils droit et il ny a pas de nuds gaux.
Un arbre binaire de recherche est intressant puisquil est
toujours possible de connatre dans quelle branche de
larbre se trouve un lment et de proche en proche le
localiser dans larbre. On peut aussi utiliser un arbre binaire
de recherche pour ordonner une liste dlments.
Recherche dans un arbre binaire de recherche
Algorithme Chercher (racine : ^Nud , X : lment)
Si ( racine = Nil) alors
retourner 0
Sinon
Si( racine^.info = X ) alors
retourner 1
Else
Si (X < racine^.info ) alors
retourner Chercher(racine^.FilsG, X)
Else
retourner Chercher (racine^.FilsD, X)
Finsi
FinSi
FinSi
Fin
Insertion dans un arbre binaire de recherche
Llment ajouter est insr l o on laurait trouv sil avait
t prsent dans larbre. Lalgorithme dinsertion recherche
donc llment dans larbre et, quand il aboutit la conclusion
que llment nappartient pas larbre (il aboutit la terre),
il insre llment comme fils du dernier nud visit.
Algorithme Insrer (racine : ^Nud, X : lment )
Si (racine = nil) alors
ajouter un nud pour X cet endroit
Sinon
Si (racine^.info = X)
Ecrire ("llment insrer existe dj dans larbre")
Sinon
Si (X> racine^.info)
Insrer (racine^.FD, X)
Sinon
Insrer (racine^.FG, X)
Fin
Suppression dans un arbre binaire de recherche


1
er
cas : llment supprimer na pas de
fils il est terminal et il suffit de le
supprimer
Suppression dans un arbre binaire de recherche

2
me
cas : llment a un fils unique on
supprime le nud et on relie son fils
son pre

Suppression dans un arbre binaire de recherche

3
me
cas : llment supprimer a deux
fils on le remplace par son successeur
qui est toujours le minimum de ses
descendants droits.
Merci pour votre attention !

You might also like