Algo 00
Algo 00
Algorithmique
, par
Introduction à l'algorithmique
27 septembre 2010 Une grosse partie de ces transparents est dérivée de ceux de
Sylvain Peyronnet (donnés à l'Épita en 2005).
D'autres sont inspirés des supports de cours de Erik D. Demaine
et Charles E. Leiserson au MIT : http://ocw.mit.edu/OcwWeb/
Electrical-Engineering-and-Computer-Science/
6-046JFall-2005/LectureNotes/
A. Duret-Lutz Algorithmique 1 / 96 A. Duret-Lutz Algorithmique 2 / 96
Notion d'algorithme
Partie 1 : Notion d'algorithme, complexité
1
1 Multiplication
Entrée : deux entiers a et b Donner une dénition précise de la notion d'algorithme est assez
Sortie : leur produit ab dicile et complexe.
Algorithme : celui de l'école Il existe plusieurs dénitions mathématiques depuis les années 30.
Plus Grand Commun Diviseur (PGCD)
Objectifs : pouvoir raisonner facilement sur les algorithmes, les
composer, les prouver, calculer le coût de leur exécution (temps,
2
Fait :
Toutes ces dénitions sont équivalentes Dans ce cours, on étudie seulement des problèmes pour lesquels il
Thèse de Church : existe des algorithmes.
Tout ce qui est calculable intuitivement est aussi En fait, on s'intéressera aux problèmes pour lesquels il existe des
calculable par les objets formels précédemment cités algorithmes ecaces.
Mais :
Il existe des problèmes non calculables (indécidables) Un exemple typique de problème décidable pour lequel il n'y a pas
Exemple : problème de l'arrêt d'algorithme ecace : le jeu d'échec (le nombre de congurations est
Entrée : Un algorithme (programme) A et une entrée I environ 10 ).
50
1 Notion d'algorithme On veut une mesure pour comparer des algorithmes qui résolvent le
même problème (ou non !). On voudrait que la complexité :
2 Mesure de complexité ne dépende pas de l'ordinateur
Comment mesurer ? ne dépende pas du langage de programmation
Exemple du tri par insertion
Analyse asymptotique et ordres de grandeur ne dépende pas du programmeur
Rappel sur les arbres soit indépendante des détails l'implémentation
Tri fusion etc.
Théorème général pour les équations de récurrence
qu'il utilise. Il sut de compter les instructions et de les pondérer par 4 while i > 0 and A[i ] > key do
leur coût. 5 A[i + 1] ← A[i ]
6 i ← i − 1
Tri par insertion : coût en temps Tri par insertion : cas favorable et défavorable
InsertionSort(A) coût fois Cas favorable : le tableau est trié. j = 1.
t
1 for j ← 2 to length(A) do c n 1
2 key ← A[j ] c n − 1
2
T n ( ) = c1 n + c2 (n − 1) + c3 (n − 1) + c4 (n − 1) + c7 (n − 1)
3 i ← j − 1 c n − 1
P 3
C'est une fonction linéraire du style an + b.
4 while i > 0 and A[i ] > key do c Pnj= tj
5 A[i + 1] ← A[i ]
4
n
(t − 1)
2
Cas défavorable : le tableau P
est trié par ordre décroissant. tj = j.
Pnj = j Rappelons que nj= j = n(n+ ) − 1 et
c 5 2 1
6 i ← i − 1 c
j = tj − 1)
6 ( Pn n(n− ) .
2 2
j = (j − 1) =
2
7 A[i + 1] ← key n − 1
1
c 7 2 2
T n( ) = c1 n + c2 (n − 1) + c3 (n − 1) ( + 1)
( ) = c1 n + c2 (n − 1) + c3 (n − 1) + c4 −1
n n
X n X n X n T n
2
+ c4 tj + c5 (tj − 1) + c6 (tj − 1) + c7 (n − 1)
( − 1) ( − 1)
+ c7 ( n − 1 )
n n n n
j =2 j =2 j =2 + c5 + c6
2 2
Cas le plus favorable ? Cas le plus défavorable ? C'est une fonction quadratique du style an 2
+ bn + c .
A. Duret-Lutz Algorithmique 14 / 96 A. Duret-Lutz Algorithmique 15 / 96
Cas moyen ? Indépendance vis-à-vis de la machine
Le cas le plus favorable est la borne inférieure
Le cas le plus défavorable est la borne supérieure
Le cas général se situe entre les deux (en toute logique !)
On fait parfois des analyses de cas moyen : Dans nos formules de T (n), les coecients c , c , . . . , c dépendent
1 2 7
Tableau d'entrée = n nombres tirés au hasard (on suppose une de la machine utilisée.
loi uniforme). Pour une cléf choisie ligne 2 en moyenne la moitié On souhaite :
du tableaux lui est supérieur et l'autre moitié lui est inférieure.
Donc tj = t . ignorer les constantes qui dépendent des machines,
P 2
P
On a nj= t = n(n+ )− et nj= t − 1 = n(n− )+
1 2 3 2 étudier la croissance de T (n) lorsque n → ∞.
2 2 4 2 2 4
n (n − 3) + 2 n (n − 3) + 2
+c +c + c (n − 1)
4 5
4 6 7
n log ln n
40
3
n e n
2
n 2
n n
2n Supposons 10 opérations par seconde.
6
n log 2
n n n log 2
n n
2
n
3
2n
30 10 2
6.6 µs 0.1 ms 0.6 ms 10 ms 1s 4 · 10 ans
6
n log 10
n
10 3
9.9 µs 1 ms 10 ms 1s 16.6 min
10 4
13.3 µs 10 ms 0.1 s 1.6 min 11.6 j
20 n
10 5
16.6 µs 0.1 s 1.6 s 2.7 h 347 ans
10 6
19.9 µs 1s 19.9 s 11.6 j 10 ans
6
10 /2
10 7
23.3 µs 10 s 3.9 min 3.17 ans
10 26.6 µs 1.6 min 44.3 min 317 ans
n
8
√
n 10 9
29.9 µs 16.6min 8.3 h 31709 ans
ln n
0 5 10 15 20
A. Duret-Lutz Algorithmique 18 / 96 A. Duret-Lutz Algorithmique 19 / 96
Équivalence asymptotique de fonctions Complexité asymptotique du tri par insertion
Cas favorable
Θ(g (n)) = {f (n) | ∃c1 ∈ R+? , ∃c2 ∈ R+? , ∃n0 ∈ N, T n ( ) = c1 n + c2 (n − 1) + c3 (n − 1) + c4 (n − 1) + c7 (n − 1)
∀n ≥ n0 , 0 ≤ c1 g (n) ≤ f (n) ≤ c2 g (n)} = Θ(n)
Impose que f et g soient positives asymptotiquement. Cas défavorable
Par convention on note f (n) = Θ(g (n)) au lieu de ( + 1)
( ) = c1 n + c2 (n − 1) + c3 (n − 1) + c4 −1
n n
2
T n
f (n) ∈ Θ(g (n))
( − 1) ( − 1)
+ c7 (n − 1) = Θ(n2 )
n n n n
Si a > 0, on a a n + a n + a = Θ(n ).
2 2
2
1 0
2 + c5
2
+ c6
2
Par exemple on pose c = et c = a , et on montre
a
2 1
2
2
3 2
2 Cas moyen
( + 1) − 2
a a a 3a ( ) = c1 n + c2 (n − 1) + c3 (n − 1) + c4
n n
4
2 1 0 2 T n
≤a + + ≤
2 |n {z n } 22
2
( − 3) + 2 ( − 3) + 2
+ c7 (n − 1) = Θ(n2 )
n n n n
n→∞ + c5 + c6
→0 quand
4 4
A. Duret-Lutz Algorithmique 20 / 96 A. Duret-Lutz Algorithmique 21 / 96
Le choix est bon si le nombre total d'opérations est proportionnel au 2 key ← A[j ] c n − 1 2
4
T n
( − 3) + 2 ( − 3) + 2
+ c7 (n − 1) = Θ(n2 )
n n n n
+ c5 + c6
4 4
A. Duret-Lutz Algorithmique 23 / 96 A. Duret-Lutz Algorithmique 24 / 96
= Θ(n2 )
Notons que
Cas moyen f (n) = Θ(g (n)) ⇐⇒ f (n) = O(g (n))
et f (n) = Ω(g (n)).
( + 1) − 2
n n Ou encore Θ(g (n)) = O(g (n)) ∩ Ω(g (n)).
( )=
4
T n
g (n )
Dénissons l'ordre (partiel) suivant :
Si nlim = ∞ alors f (n) = O(f (n)) et g (n) 6= O(f (n)).
→∞ f (n ) Θ(f (n)) ≤ Θ(g (n)) si f = O(g (n))
f (n ) = O(g (n )) ssi g (n ) = Ω(f (n )). Θ(f (n)) < Θ(g (n)) si f = O(g (n)) et g 6∈ O(f (n))
Énumérer par ordre croissant les ensembles Θ(. . .) des fonctions
suivantes : √
n
n , 2 , n log n , ln n , n + 7n , log n ,
5 n n− , n , n + log n,
n, e , 2
1 2 2
a ≺ b, a ≺ c , a ≺ d , b ≺ e , b ≺ f , c ≺ g , f ≺ h, f ≺ i .
1 1 1 1 1 1 1 1 Dénition récursive
D'où une représentation arborescente de A. Un arbre enraciné est un ensemble de un ou plusieurs n÷uds tel
On note 4 la clôture réexive et transitive. que
4 relation d'ordre (non total) sur A. l'un des n÷uds r est désigné comme la racine
Ensemble ordonné le reste des n÷uds est partionné en n ≥ 0 ensembles disjoints
Soit (A, 4) un ensemble ordonné. ≺ est l'ordre strict associé à A. T , T , . . ., Tn tels que chacun de ces ensembles est lui-même
1 2
Maj?( a) = {x ∈ A | a ≺ x } Min?( a) = {x ∈ A | x ≺ a}
de r
Arbres mathématiques Le degré d'un n÷ud est le nombre de sous-arbres dont il est la
Un ensemble ordonné (A, 4) est un arbre ssi racine.
A est ni
Merge-Sort(A, l , r ) T(1) ( )
T n
cn /2 cn /2 cn
1 if l < r then Θ(1) Θ(1)
= blog nc
2 q ← b(l + r )/2c Θ(1)
3 Merge-Sort(A, l , q ) T (bn /2c) cn /4 cn /4 cn /4 cn /4 cn
3 Merge-Sort(A, q + 1, r ) T (dn /2e)
h
4 Merge(A, l , q , r ) Θ(n)
Θ(1) Θ(n)
On a donc la relation de récurrence
( n feuilles
Θ(1) si n = 1
T (n ) = On a donc T (n) = Θ(n log n).
2T (n/2) + Θ(n) si n > 1
A. Duret-Lutz Algorithmique 36 / 96 A. Duret-Lutz Algorithmique 37 / 96
Théorème général Applications du théorème
Soit à résoudre
( ( ) = 2T (n/2) + Θ(n)
T n
Θ(1) si n ≤ n 0 a = b = 2, n
logb a
= n. On a donc T (n) = Θ(n log n).
T (n ) =
aT (n /b ) + f (n ) si n > n √
T (n ) = 4T (n /2) +
0
n
√
avec a ≥ 1, b > 1, n ∈ N. 0 a = 4, b = 2, n
logb a
= n2 . = 1 et n = O(n2−1 ), on a donc
Alors 2
T (n ) = Θ(n )
( ) = 3T (n/3) + n2
Si f (n) = Θ(n b a ), alors T (n) = Θ(n b a log n).
T n
log log
logb a
a = 3, b = 3, n = n. = 1 et n = Ω(n + ), d'autre part
2 1 1
Ces deux tris sont stables : l'ordre des éléments égaux est préservé. Tri en place, mais instable (à cause de l'échange).
A. Duret-Lutz Algorithmique 44 / 96 A. Duret-Lutz Algorithmique 45 / 96
Arbre parfait Arbre parfait partiellement ordonné et tas
Un arbre parfait partiellement ordonné est un arbre parfait étiqueté de
façon à ce que l'étiquette d'un n÷ud soit supérieure à celles de ses
Un arbre parfait est un arbre binaire équilibré dont les feuilles du ls.
dernier niveau sont toutes à gauche.
18
12 11
6 10 9 4
2 3 8
6 10 9 4 Heapify(A, i , m)
2 3 8 1 l ←LeftChild(i ) ( ) ≤ T (2n/3) + Θ(1) avec n la
T n
2 r ←RightChild(i ) taille du sous-arbre commençant en i
A = 18 12 11 6 10 9 4 2 3 8 3 if l ≤ m and A[l ] > A[i ] et 2n/3 le nombre maximum de
4 then largest ← l n÷uds du sous-arbre recursivement
L'indice 1 correspond à la racine 5 else largest ← i exploré.
Parent(i ) = bi /2c (si i > 0) 6 if r ≤ m and A[r ] > A[largest ]
7 then largest ← r On en déduit T (n) = O(log n)
LeftChild(i ) = 2i (s'il existe)
8 if largest 6= i then Aussi T (h) = O(h) avec h la hauteur
RightChild(i ) = 2i + 1 (s'il existe) 9 A[i ] ↔ A[largest ] de l'arbre commençant à i .
10 Heapify(A, largest , m)
La propriété du tas : ∀i > 0, A[Father(i )] ≥ A[i ].
A. Duret-Lutz Algorithmique 48 / 96 A. Duret-Lutz Algorithmique 49 / 96
Opérations sur le tas (2) : Build-Heap Opérations sur le tas (3) : Build-Heap
Calculons T (n) pour Build-Heap de façon plus précise.
Entrée : un tableau A quelconque. La hauteur d'un tas de n n÷uds est blog nc.
Sortie : le tableau A réordonné en tas. Le nombre de sous arbres de hauteur h dans un tas de n n÷uds est
Build-Heap(A)
1 for i ← blength(A)/2c down to 1 do au plus dn/2h+ e. 1
1 Build-Heap(A)
2 for i ← length(A) down to 2 do Idée générale
3 A[1] ↔ A[i ] On partage le tableau en deux sous-tableaux tels que tous les
4 Heapify(A, 1, i − 1) éléments du premier soient plus petits que ceux du second. On trie
ces deux tableaux recursivement.
On a bien sûr :
Comment partager ?
T n( )= O ( )
n
| {z }
+O( |{z}
n log
|{z}
n ) = O(n log n ) On choisit une clé, qui sert de pivot. Par échanges successifs, on
Build-Heap
boucle Heapify ordonne le tableau en deux blocs :
au début, les éléments inférieurs (ou égaux) au pivot
à la n, les éléments supérieurs (ou égaux) au pivot
Notre choix : le pivot est le premier élément.
O( n )
1. prétendument, car la récursion consomme de l'espace en log
A. Duret-Lutz Algorithmique 52 / 96 A. Duret-Lutz Algorithmique 53 / 96
Tri rapide : algorithme Complexité du tri rapide
Cas défavorable
Entrée : un tableau A d'entier, Entrée : un tableau A d'entier, Le partionnement crée un arbre de découpe très déséquilibré.
premier indice l , dernier indice r premier indice l , dernier indice r Cela se produit si l'entrée est déjà triée (dans un sens ou l'autre).
Sortie : le tableau A trié par Sortie : un entier p et le tableau A
ordre croissant réordonné tq A[l ..p] ≤ A[p + 1..r ]. T n ( ) = Θ(n) + Θ(1) + T (n − 1)
Quick-Sort(A, l , r ) Partition(A, l , r ) = T (n − 1) + Θ(n)
1 if l < r then 1 x ← A[l ] ; i ← l − 1 ; j ← r + 1 = Θ(n2 )
2 p ← Partition(A, l , r ) 2 repeat forever
3 Quick-Sort(A, l , p) 3 do i ← i + 1 until A[i ] ≥ x Cas favorable
4 Quick-Sort(A, p + 1, r ) 4 do j ← j − 1 until A[j ] ≤ x Le partionnement crée un arbre de découpe équilibré.
5 if i < j then
6 A[i ] ↔ A[j ] ( ) = Θ(n) + 2T (n/2)
T n
7 else
8 return j C'est la même équation que pour le tri fusion. On sait que la
T (n) = Θ(n) si n = r − l + 1.
Partition
solution est T (n) = Θ(n log n).
A. Duret-Lutz Algorithmique 54 / 96 A. Duret-Lutz Algorithmique 55 / 96
T (n ) = T (n − 1) + T (i ) + c (n − 1 + 1)
(n − 1)(n − 2) i= 1
n −1 n −1
1X 2 X 2 n − 2 n − 2
T (n ) = (T (i ) + T (n − i )) + Θ(n) = ( ) + cn = T (n − 1) + T (n − 1) + c (n − 1) 1− +c
n − 1 − 1 i =1
T i
n n − 1 n − 1 n − 1
i =1
D'autre part : T (n − 1) + 2c
n
=
n − 1
n−2
2 X
( − 1) = ( ) + c (n − 1) On divise à droite et à gauche par n :
− 2 i =1
T n T i
n
T n ( ) ( − 1)
T n 2c
= +
n n − 1 n
on pose Y (n) = T n(n) Que se passe-t-il si tous les éléments du tableau à trier ont la
n
même valeur ?
2c X 1
(n) = Y (n − 1) + = 2c
On a l'impression qu'un tableau aléatoire sera trié plus
Y
n i
i =1
n rapidement qu'un tableau trié. Comment faire en sorte que
X 1 l'algorithme aie la même complexité (en moyenne) sur les
T n ( ) = 2cn
i =1
i
tableaux aléatoires que sur les tableaux triés ?
Pn 1
La formule d'Euler : i =1 i = ln n + γ + o (1).
On en déduit
T n ( ) = Θ(n)Θ(log n) = Θ(n log n)
A. Duret-Lutz Algorithmique 60 / 96 A. Duret-Lutz Algorithmique 61 / 96
Tri rapide stochastique Autre idée : pivot médian
L'idée est simple : on choisit le pivot aléatoirement dans le tableau.
RandomizedPartition(A, l , r )
1 x ← A[Random(l , r )] ; i ← l − 1 ; j ← r + 1
2 repeat forever (La médiane de 2k + 1 valeurs est la (k + 1) plus grande valeur.)
e
4 do j ← j − 1 until A[j ] ≤ x
3 do i ← i + 1 until A[i ] ≥ x L'idée : on choisit comme pivot pour la partition la médiane de
5 if i < j then quelques valeurs du tableau.
6 A[i ] ↔ A[j ]
Par exemple la médiane des trois premières valeur.
7 else Ou mieux (pourquoi ?) : la médiane des A[l ], A[b l +r c] et A[r ].
8 return j 2
Origine
On a T (n) = O(n ) de façon générale, mais T (n) = Θ(n log n)
2
David Musser, 1997
en moyenne sur des entrées distribuées uniformément. Utilisé dans la Standard Template Library de SGI. (std::sort)
En pratique le tri rapide est plus rapide que les autre tris Intérêt
présentés jusqu'à présent pour des valeurs de n pas ridiculement Modication du tri rapide de façon à ce que T (n) = Θ(n log n)
petites. toujours. Donc : tri en place et instable.
2
Pour les petites valeurs, le tri par insertion est un bon choix. Idée
Détecter les séquences qui posent problème au tri rapide, et
L'implémentation de qsort() dans la GNU Libc (et d'autres) : eectuer un tri par tas dans ce cas.
Version non-récursive du tri rapide. En pratique
Choix du pivot médian des extrémités et du milieu.
≤4
On borne le nombre d'appels récursifs à O(log n).
Tri par insertion dès que la partition possède éléments.
Musser suggère 2blog nc.
2. prétendument, comme pour le QuickSort
A. Duret-Lutz Algorithmique 64 / 96 A. Duret-Lutz Algorithmique 65 / 96
Tri introspectif : algorithme Résumé des complexités
Sortie : Une permutation ha0 , a0 , . . . an0 i de la séquence d'entrée 3 Tris comparatifs 4 Tris linéaires
1
Rangs et médians
à eectuer pour obtenir le tableau trié.
Opérations sur le tas 7
Cas favorable
Si les B [i ] sont de taille ni = 1, les n appels à InsertionSort de la Espérance d'une variable aléatoire
ligne 5 prennent tous Θ(1). C'est sa X
valeur attendue, ou moyenne.
On obtient une complexité en Θ(n). E[ X ]= x Pr{ X = x}
x
Cas défavorable
Si (1) tous les éléments se retrouvent dans le même paquet, et (2) Variance
se paquet est ordonné à l'envers (pire cas pour le tri par insertion), Var[ X ] = E[(X − E[X ])2 ] = E[X 2 ] − E2 [X ]
alors la ligne 5 demande Θ(n ) opérations.
2
Loi binomiale
On obtient une complexité en Θ(n ). 2
On lance n ballons dans r paniers. Les chutes dans les paniers sont
Cas moyen équiprobables (p = 1/r ). On note Xi le nombre de ballons dans le
Que vaut ni en moyenne ? panier i . On a Pr{Xi = k } = Ckn pk (1 − p)n−k . On peut montrer
Que vaut nPi en moyenne ?
2
E [Xi ] = np et Var[Xi ] = np (1 − p ).
Que vaut ni =− O(E [ni ]) ?
1
0
2
3 do ∞
X ∞ k
4 j ←Random(1, length (A))
−i X
E[ i +
t − 1] = k Pr{ i +
t − 1 = k} =
n i
k
5 until C [j ] = 0
1 1
n n
k =0 k =0
6 C [j ] ← 1
Pour |x | < 1 on sait
P∞ k
x =
1
. En dérivant et en multipliant
7 B [i ] ← A[j ] P∞ k =0k x
1−x
1 − ni 2
2
n n n −i
n2
A. Duret-Lutz Algorithmique 76 / 96 A. Duret-Lutz Algorithmique 77 / 96
Mélange naïf : étude (2/2) Mélange plus mieux
−1
E[ i ] = 1 +
t
i
n − i + 1
=
n
n
+1−i
Le nombre moyen d'exécutions de la ligne 4 est Entrée : un tableau A
n n n Sortie : le tableau A mélangé
X X X 1 BetterRandomizeArray(A)
E[ i ] =
t
n
n + 1 − i
= n
i =1 i =1
k =n+1−i
k =1
k 1 for i ← 1 to length(A) − 1 do
= n(ln n + Θ(1)) = Θ(n log n) 2 j ←Random(i , length (A))
3 A[i ] ↔ A[j ]
On en déduit que la complexité moyenne de ce mélange est
T (n ) = Θ(n log n ). On a évidement T (n) = Θ(n) dans tous les cas.
Dans le meilleur cas, on a T (n) = Θ(n) (le random est toujours le
bon !).
Dans le pire cas (le random est toujours le mauvais) l'algorithme ne
termine pas. Oups !
A. Duret-Lutz Algorithmique 78 / 96 A. Duret-Lutz Algorithmique 79 / 96
3 if v = A[m] then
5
Tri par sélection
Tri par tas 6 Recherche dans un tableau trié 4 return m
Structure de tas 5 else
Opérations sur le tas 7 Rangs et médians 6 if v < A[m] then
Tri rapide Minimum 7 return BinarySearch(A, l , m − 1, v )
Tri introspectif Sélection 8 else
Bornes de complexité des Sélection stochastique 9 return BinarySearch(A, m + 1, r , v )
tris comparatifs Sélection en O(n) 10 else
11 return 0
A. Duret-Lutz Algorithmique 80 / 96 A. Duret-Lutz Algorithmique 81 / 96
Recherche dans un tableau trié (compexité) Arbre de décision pour une recherche par
comparaison (1/2)
( ) ≤ T (n/2) + Θ(1)
T n L'arbre de décision pour un algorithme de recherche dans un tableau
A est un arbre binaire dont les n÷uds internes sont étiquetés par des
On en déduit T (n) = O(log(n)). indices de A de la façon suivante :
On peut montrer que cette complexité est optimale. la racine est étiquetée par l'indice du premier élément avec
Concentrons nous sur le cas v 6∈ A. Une preuve que v 6∈ A est un lequel A compare v
énoncé de la forme si l'étiquette d'un n÷ud est i , l'étiquette du ls gauche est
∃i ∈ [[1, n[[, A[i ] < v < A[i + 1] ou
l'indice du n÷ud avec lequel l'algorithme compare v si v < A[i ],
l'étiquette du ls droit est l'indice du n÷ud avec lequel
v < A[1] ou
l'algorithme compare v si v > A[i ].
[ ]<v
A n
Les feuilles de A sont étiquetées par les preuves que v 6∈ A.
Si v 6∈ A, un algorithme de comparaison ne peut s'arrêter que s'il
possède une preuve. (Cet arbre peut être étendu en rajoutant une feuille a chaque sommet
interne étiqueté par i . Cette feuille correspond au résultat v = A[i ].)
A. Duret-Lutz Algorithmique 82 / 96 A. Duret-Lutz Algorithmique 83 / 96
L'algorithme de comparaison (représenté par l'arbre de décision) ne Opérations sur le tas 7 Rangs et médians
peut distinguer ces deux tableaux, donc il donne un résultat incorrect. Tri rapide Minimum
Le nombre de n÷uds internes est donc supérieur à n. Tri introspectif Sélection
Bornes de complexité des Sélection stochastique
Le nombre de comparaisons eectuées dans le pire cas est donc tris comparatifs Sélection en O(n)
supérieur à blog nc.
On a prouvé T (n) = Ω(log n) en pire cas.
A. Duret-Lutz Algorithmique 84 / 96 A. Duret-Lutz Algorithmique 85 / 96
Recherche du minimum Sélection
Minimum(A)
1 min ← A[1]
2 for i ← 2 to length(A) do Problème de la sélection
3 if min > A[i ] then Entrée : Un ensemble A de n nombres distincts et un nombre
4 min ← A[i ] i ∈ [[1, n ]].
5 return min Sortie : L'élément x ∈ A qui est plus grand que i − 1 autres
On a T (n) = n − 1 = Θ(n) comparaisons. éléments de A exactement.
On en déduit que le problème de la recherche du miminum est en Peut être résolu en O(n log n)
O(n). Est-il possible de faire mieux ? Il sut de trier A et retourner A[i ].
La recherche du minimum peut être vu comme un tournoi, remporté
par le plus petit élément. Chaque comparaison est un match. Tout On peut mieux faire !
élément hormis le vainqueur perdra au moins un match. Il faudrait Le problème est en Θ(n).
donc n − 1 comparaisons pour trouver le minimum.
Le problème de la recherche du minimum est donc en Θ(n).
A. Duret-Lutz Algorithmique 86 / 96 A. Duret-Lutz Algorithmique 87 / 96
n−1
Pire cas 1 X
≤ (max(i , n − i )) + Θ(n)
La partition crée systématiquement deux ensembles de taille 1 et n − 1 i =1
T
8
k n
( )≤ ( ) + Θ(n)
−1
T n T i
n k =bn/2c
i =bn/2c
Preuve
n −1
X (n − 1 + bn/2c)(n − bn/2c) n
2
− n + bn/2c − bn/2c2
= =
2 2
k
=
3n 2
−3
≤
3n 2
pour n ≤ n . 0 8 8 8
A. Duret-Lutz Algorithmique 90 / 96 A. Duret-Lutz Algorithmique 91 / 96
i =bn/ c 2 médians.
3cn(n − 1) + 3cn 3cn 3c (n − 1) + 3c Partitionner le tableau d'entrée autour du médian des médians
T (n ) ≤ + Θ(n) ≤
4(n − 1) 4
+
4(n − 1)
+ Θ(n) en utilisant une version modiée de Partition. Notons k le
cn 3c 3c cn
nombre d'éléments de la région inférieure.
T (n ) ≤ cn − + + + Θ(n) ≤ cn + Θ(n) −
4 4 4(n − 1) 4 Appeler Selection récursivement pour trouver le i plus petit e
cn 3cn 19cn cn
( ) ≤ Θ(n) + + = Θ(n) + ≤ cn + Θ(n) −
5 4 20 20
T n
À la louche... Au moins un quart des éléments sont plus petits que le c peut être choisi assez grand pour que cn domine le Θ(n)
20
médian et un quart des éléments sont plus grands. (On peut être plus ( ) ≤ cn
précis.) Dans le pire cas, la partition retourne donc un sous-tableau
T n
A. Duret-Lutz Algorithmique 96 / 96