Académique Documents
Professionnel Documents
Culture Documents
1 L'algorithme
1.1 Principe
1
def tri_rapide(L):
if L == []:
return([])
a = L[0]
L1 = [k for k in L[1:] if k <= a]
L2 = [k for k in L[1:] if k > a]
return(tri_rapide(L1) + [a] + tri_rapide(L2))
def partition(t):
n, pivot = len(t), t[0]
limite = 1
for indice in range(1, n):
if t[indice] < pivot:
t[indice], t[limite] = t[limite], t[indice]
limite += 1
t[0], t[limite - 1] = t[limite - 1], t[0]
1
# tri rapide en place
'''La fonction partition sépare les éléments de t[debut:fin] en
deux à l'aide du pivot.
Invariants, vérifiés à l'entrée de la boucle :
1
2 Le tri rapide avec une pile
4
def partition(t, debut, fin):
pivot = t[debut]
limite = 1 + debut
for k in range(1 + debut, fin):
if t[k] < pivot:
t[k], t[limite] = t[limite], t[k]
limite += 1
t[debut], t[limite - 1] = t[limite - 1], t[debut]
return limite - 1 # retourne la nouvelle
# position du pivot
def tri_rapide_a_mains_nues(t):
n = len(t)
tache = [0,n] # intervalle à trier
pile_des_taches = [tache]
while pile_des_taches != []:
tache = pile_des_taches.pop()
[debut, fin] = tache # intervalle à trier
if fin > 1 + debut:
pos_pivot = partition(t, debut, fin)
pile_des_taches.append([debut, pos_pivot])
pile_des_taches.append([1 + pos_pivot, fin])
1
3 Complexité
Le cas où à chaque étape, le tableau se sépare miraculeusement en deux tableaux de même longueur.
Quelles sont les valeurs de n possibles ?
Réponse
n = 2q − 1 ; dans ce cas, le nombre de comparaisons vérie :
n−1
C (n) = n − 1 + 2.C
2
3.3 En moyenne
On peut montrer que le nombre moyen de comparaisons Cn sur un tableau de taille n vérie :
n−1
2X
Cn = n − 1 + Cj
n j=0
avec C0 = C1 = 0 ; on en tire :
n−1
X j
Cn = 2(n + 1)
j=1
(j + 1) (j + 2)
puis
Cn ∼ 2n. ln n
Remarque préliminaire
En utilisant la convexité de x → x. log2 (x) :
x+y
∀x > 0, ∀y > 0, (x + y) .log2 ≤ x.log2 x + y.log2 y
2
6
Démonstration
Pour N = 1 ou N = 2, c'est clair.
Soit N ≥ 3 et A un arbre binaire à N feuilles.
Ses deux sous-arbres ont N1 et N2 feuilles, avec N = N1 + N2 .
D'après l'hypothèse de récurrence :
log2 (N1 ) ≤ h1 , log2 (N2 ) ≤ h2
D'où :
N1 h1 + N2 h2 1
hm = 1 + ≥1+ (N1 . log2 (N1 ) + N2 . log2 (N2 ))
N N
Donc
1 N1 + N2
hm ≥ 1 + . (N1 + N2 ) .log2 = log2 (N )
N 2
Conséquence
Pour N = n! :
hm ≥ log2 (n!)
Par ailleurs, ˆ n
ln (n!) ≥ ln (t) dt = n.ln (n) − n + 1
1
On en déduit que tout algorithme de tri nécessite en moyenne au moins C.n. ln (n) comparaisons.
7
import random as rd
N = 10
def tri(t):
n = len(t)
compteur = [0 for k in range(3*n + 1)]
for k in range(n):
compteur[t[k]] += 1
indice = 0
for i in range(3*n + 1):
for j in range(compteur[i]):
t[indice] = i
indice += 1