TD 7 : Algorithmes de tri

publicité
TD 7 : Algorithmes de tri - Diviser pour régner
PC/PC* - Lycée Thiers
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Exercice 1 : Algorithme de tri
Enoncé
Correction
Exercice 2 : Le tri par insertion
Enoncé
Corrigé
Exercice 3 : Tri rapide
Enoncé
Corrigé
Exercice 4 : Tri fusion
Enoncé
Corrigé
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Correction
Exercice 1 : Algorithme de tri
Un algorithme de Tri prend en paramètre un tableau d’éléments
d’ordonnables, par exemple une liste de nombres et renvoie le tableau trié
dans le sens croissant.
Exercice 1. Écrire un algorithme de tri de son choix. Quels sont sa
complexité dans le pire des cas ? Dans le meilleur des cas ?
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Correction
Exercice 1 : Algorithme de tri
● Le tri par sélection :
def triSelection(T):
"""Algorithme de tri par sélection"""
N = len(T)
# Balayage
for k in range(N-1):
# Recherche du minimum à partir de k
ind = k
for i in range(k,N):
if T[i] < T[ind]:
ind = i
# Placement du minimum à l’indice k
T[ind], T[k] = T[k], T[ind]
return T
de complexité quadratique dans le pire et le meilleur des cas.
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Correction
Exercice 1 : Algorithme de tri
● Le tri à bulle :
def triBulle(T):
"""Tri à bulle"""
N = len(T)
chgt = True
while chgt:
for k in range(N-1):
chgt = False
if T[i]>T[i+1]:
T[i], T[i+1] = T[i+1], T[i]
chgt = True
N -= 1
return T
● Complexité linéaire dans le meilleur des cas (pour un tableau déjà trié),
quadratique dans le meilleur des cas.
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Corrigé
Exercice 2 : Le tri par insertion
Exercice 2. Tri par insertion. C’est celui que l’on utilise habituellement
dans la vie courante, par exemple, pour trier un paquet de carte :
On constitue (imaginairement) 2 tas :
– l’un dans la main droite, contenant toutes les cartes avant tri,
– l’autre dans la main gauche, contenant les cartes déjà triées,
Initialement la main gauche est vide.
Chaque étape consiste à :
– prendre la première carte du tas non trié
– L’insérer progressivement à sa bonne place dans le tas trié, en la
faisant descendre d’une position tant que sa valeur reste inférieure à
celle de la carte située en dessous-d’elle.
Après chaque étape le tas non trié contient une carte de moins, le tas trié
une carte de plus.
A la fin du tri la main droite est vide. La main gauche contient toutes les
cartes, triées.
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Corrigé
Exercice 2 : Le tri par insertion
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Corrigé
Exercice 2 : Le tri par insertion
1. Ecrire une fonction triInsertion prenant en paramètre une liste
de nombres et qui applique un tri par insertion pour le trier dans le
sens croissant.
2. Quel invariant de boucle permet de justifier qu’à la fin de
l’algorithme le tableau est trié ?
3. Complexité dans le meilleur des cas : quel est le meilleur des cas ?
Quelle est alors la complexité ?
4. Complexité dans le pire des cas : quel est le pire des cas ? Quelle est
alors la complexité ?
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Corrigé
Exercice 2 : corrigé
def triInsertion(T):
"""Tri par insertion"""
N = len(T)
# Balayage
for k in range(1,N):
# Insertion
i = k
while i > 0 and T[i-1] > T[i]:
T[i-1], T[i] = T[i], T[i-1]
i -= 1
return T
● Invariant de boucle : ”Après k insertions les k premiers éléments du
tableau sont ordonnés dans le sens croissant.” (pour la boucle for).
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Corrigé
Exercice 2 : corrigé
Version optimisée :
def triInsertion(T):
"""Tri par insertion"""
N = len(T)
# Balayage
for k in range(1,N):
# Insertion
x = T[i]
i = k
while i > 0 and T[i-1] > x:
T[i-1] = x
i -= 1
T[i] = x
return T
● Invariant de boucle : ”Après k insertions les k premiers éléments du
tableau sont ordonnés dans le sens croissant.” (pour la boucle for).
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Corrigé
Exercice 2 : corrigé
● Meilleur des cas : celui d’un tableau déjà trié. La complexité est linéaire
(chaque insertion est en O(1)).
● Pire des cas : celui d’un tableau ordonné dans le sens décroissant :
complexité quadratique : la k-ième insertion se fait en Θ(k).
N−1
N−1
∑ Θ(k) = Θ ( ∑ k) = Θ (
k=1
k=1
PC/PC* - Lycée Thiers
N(N − 1)
) = Θ(N 2 ) .
2
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Corrigé
Exercice 3 : Tri rapide
Ce tri particulièrement rapide, est basé sur le principe de diviser pour
régner :
– Choisir arbitrairement un élément e dans le tableau T,
e
– Décomposer les autres éléments du tableau en deux sous-tableaux :
– T- constitué des éléments inférieurs à e,
– T+ constitué des éléments supérieurs à e.
T-
e
T+
– Après appels récursifs sur les deux sous-tableaux T- et T+, le tableau
T trié s’obtient en concaténant les sous-tableaux T- trié, suivi de e,
suivi de T+ trié.
T- trié
e
T+ trié
Le tableau T est alors trié.
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Corrigé
Exercice 3 : Tri rapide
Exemple : (1) Tri rapide à la main de [7, 3, 6, 4, 2, 5, 1] :
– Appel sur T = [7, 3, 6, 4, 2, 5, 1]
e = 4,
T1 = [3, 2, 1],
T2 = [7, 6, 5]
– Appel récursif sur T1 = [3, 2, 1] :
e = 2,
T11 = [1],
T12 = [3]
Ô⇒ T1 devient : T11 + [2] + T12 = [1, 2, 3]
– Appel récursif sur T2 = [7,6,5]
e = 6,
T21 = [5],
T22 = [7]
Ô⇒ T2 devient : T21 + [6] + T22 = [5,6,7]
Ô⇒ T devient : T1 + [4] + T2 = [1,2,3,4,5,6,7]
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Corrigé
Exercice 3 : Tri rapide
1. Ecrire une fonction triRapide prenant en paramètre une liste de
nombres T et qui renvoie un tableau trié contenant les mêmes
éléments que T.
2. Lorsque l’élément e est chaque fois choisi médian, quelle et la
complexité de l’algorithme ?
3. Lorsque l’élément e est chaque fois choisi extremal, quelle est la
compléxité de l’algorithme ?
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Corrigé
Exercice 3 : Corrigé
def TriRapide(T):
N = len(T)
if N <= 1:
return T
e = T.pop(N//2)
T1, T2 = [], []
for x in T:
if x <= e:
T1.append(x)
else:
T2.append(x)
return TriRapide(T1) + [e] + TriRapide(T2)
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Corrigé
Exercice 3 : Corrigé
Dans le meilleur des cas, lorsque l’élément choisi est médian :
N
N/2
N/2
N/4
⋮
1
N/4
⋮
1
1
⋮
1
1
N/4
⋮
1
1
⋮
1
PC/PC* - Lycée Thiers
1
N/4
⋮
1
1
⋮
1
1
⋮
1
TD 7 : Algorithmes de tri - Diviser pour régner
1
1
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Corrigé
Exercice 3 : Corrigé
La profondeur de l’arbre est log2 (N) puisque : N = 2log2 (N) . De l’ordre de
N opérations à chaque étage.
Ô⇒ C (N) = Θ
⎛log2 (N) k N ⎞
∑ 2 × k = Θ ((log2 (N) + 1) × N) = Θ(N log(N))
2 ⎠
⎝ k=0
Dans ce cas la complexité est en N log(N).
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Corrigé
Exercice 3 : Corrigé
Dans le pire des cas, lorsque l’élément choisi est toujours un élément
extrémal (min ou max) :
N
N −1
1
1
N −k
1
1
1
1
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Corrigé
Exercice 3 : Corrigé
La profondeur de l’arbre est N. De l’ordre de N − k opérations à chaque
”étage” k.
N
Ô⇒ C (N) = Θ ( ∑ n) = Θ (N ×
n=1
(N + 1)
) = Θ (N 2 )
2
complexité quadratique
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Corrigé
Exercice 4 : Tri fusion
Le tri fusion est un autre exemple d’algorithme de tri basé sur le principe
de ”Diviser pour régner”.
Il est basé sur le fait que fusionner deux tableaux triés en un seul tableau
trié T1, T2 se fait en temps linéaire (sur le nombre total d’éléments, dans
le pire et le meilleur des cas) :
i1, i2 = 0
T = tableau vide
TANT QUE l’on n’a pas atteint la fin d’un des tableaux:
SI T1[i1] <= T2[i2] ALORS
Insérer T1[i1] à la fin de T
incrémenter i1
SINON
Insérer T2[i2] à la fin de T
incrémenter i2
FIN TANT QUE
Insérer les éléments restants en fin de T
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Corrigé
Exercice 4 : Tri fusion
On met alors en oeuvre la récursivité :
– Décomposer le tableau en deux sous-tableaux de même longueur
(±1)
– Appliquer l’algorithme récursivement sur chacun des 2 sous-tableaux
– Puis fusionner les 2 sous-tableaux triés en un tableau trié.
1. Ecrire une fonction fusion prenant en paramètre deux listes triées,
et qui les fusionne en une liste triée dans le sens croissant, qu’elle
renverra.
2. Ecrire une fonction triFusion qui exécute le Tri fusion.
3. Quelle est sa complexité dans le pire des cas ? dans le meilleur des
cas ?
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Corrigé
Exercice 4 : correction
def fusion(T1,T2):
T = []
i1 = i2 = 0
n1, n2 = len(T1), len(T2)
while i1 < n1 and i2 < n2 :
if T1[i1] <= T2[i2]:
T.append(T1[i1])
i1 += 1
else:
T.append(T2[i2])
i2 += 1
while i1 < n1:
T.append(T1[i1])
i1 += 1
while i2 < n2:
T.append(T2[i2])
i2 += 1
return T
PC/PC* - Lycée Thiers
TD 7 : Algorithmes de tri - Diviser pour régner
Exercice 1 : Algorithme de tri
Exercice 2 : Le tri par insertion
Exercice 3 : Tri rapide
Exercice 4 : Tri fusion
Enoncé
Corrigé
Exercice 4 : correction
def triFusion(T):
N = len(T)
if N == 1:
return T
T1, T2 = triFusion(T[:N//2]), triFusion(T[N//2:])
return fusion(T1,T2)
● Dans le pire et le meilleur des cas, la fonction fusion étant de
complexité linéaire, triFusion est de complexité θ(N log(N)).
N
N/2
N/2
N/4
N/4
⋮
1
⋮
1
1
⋮
1
1
N/4
⋮
1
1
PC/PC* - Lycée Thiers
⋮
1
1
N/4
⋮
1
1
⋮
1
1
⋮
1
1
1
TD 7 : Algorithmes de tri - Diviser pour régner
Téléchargement