1 Partitionnement d`un tableau suivant un pivot 2 Implémentation à

publicité
Informatique
TD/ TP 4.2b
Tri rapide (quick sort)
On se propose ici d’implémenter l’algorithme de tri rapide en place ("quick sort") présenté en cours 4.2b.
1 Partitionnement d’un tableau suivant un pivot
1) Dérouler étape par étape l’algorithme de partitionnement en place de t = [8, 4, 2, 15, 17, 23, 0, 1]
avec le pivot t[0] = 8 en complétant les tableaux suivants.
itération initialisation
1
2
k
1
2
t[k]
m
0
t
[8, 4, 2, 15, 17, 23, 0, 1]
itération 3
k
3
t[k]
m
8
3
t
[8, 4, 2, 15, 17, 23, 0, 1]
4
4
1
2
[8, 4, 2, 15, 17, 23, 0, [8, 4, 2, 15, 17, 23, 0,
1]
1]
4
5
4
5
15
23
3
3
[8, 4, 2, 15, 17, 23, 0, [8, 4, 2, 15, 17, 23, 0,
1]
1]
itération 6
k
t[k]
m
t
7
6
7
0
1
4
5
[8, 4, 2, 0, 17, 23, 15, [8, 4, 2, 0, 1, 23, 15,
1]
17]
post traitement
[1, 4, 2, 0, 8, 23, 15, 17]
2) Expliquer en quoi consiste le post traitement qui succède aux itérations ?
On met en place le pivot 8 à sa place définitive.
2 Implémentation à partir d'une liste python
3) Ecrire une fonction echange qui prend en argument un tableau t, deux entiers i et j et échange les
éléments t[i] et t[j].
def echange(t,i,j):
x=t[i]
t[i]=t[j]
t[j]=x
Lycée Jules Ferry Cannes
Page 1 sur 3
TSI2
Informatique
TD/ TP 4.2b
Tri rapide (quick sort)
4) Ecrire une fonction segmenter qui prend en argument un tableau t, les indices de début i et de fin
j de partition t :
qui partitionne ses éléments en prenant pour pivot l’élément de gauche t[i],
qui renvoie la position finale du pivot (on utilisera en boîte noire la fonction echange
précédemment écrite).
def segmenter(T,i,j):
p = T[i] # p : pivot du segment = 1er élément de la liste à fractionner
m = i # m : indice de séparation entre G1 (valeurs ≤ p) et G2 (valeurs>p)
for k in range(i+1,j):
if T[k]<=p:
m=m+1
echange(T,m,k)
echange(T,i,m)
return m
3 Tri rapide récursif
5) Dérouler étape par étape l’algorithme de tri rapide du tableau t = [8, 4, 2, 15, 17, 23, 0, 1] (attention
ce tableau après appel de la fonction tr a la forme obtenue en fin de traitement de la question 1).
On complètera pour cela l'arbre des appels récursifs (tr est la fonction récursive de tri rapide, le
respect de l'ordre des valeurs dans les partitions est impératif dans la liste d'entrée de tr) ainsi que
le pivot obtenu à chaque appel.
tr([2,0])
2
tr([1,4,2,0])
8
tr([23,15,17])
0
tr([4])
1
tr(t)
tr([0])
4
tr([17,15])
tr([15])
15
23
17
6) Ecrire une fonction récursive tri_rapide_rec qui prend en argument un tableau t, deux entiers i et
j, et qui réalise un tri rapide du sous-tableau t[i : j].
def tri_rapide_rec(M,i,j):
T=M[:]
if i<j:
k = segmenter(T,i,j)
tri_rapide_rec(T,i,k)
tri_rapide_rec(T,k+1,j)
return T
Lycée Jules Ferry Cannes
Page 2 sur 3
TSI2
Informatique
TD/ TP 4.2b
Tri rapide (quick sort)
7) Ecrire enfin la fonction tri_rapide qui prend en argument un tableau t et réalise un tri rapide de t
(on utilisera la fonction tri_rapide_rec).
def tri_rapide(T):
return tri_rapide_rec(T,0,len(T))
4 Améliorations et performances temporelles
8)
-
Améliorer la fonction segmenter afin de :
choisir aléatoirement le pivot (on pourra importer la fonction randint du paquet random et utiliser
la commande randint(a,b), qui choisit aléatoirement un entier dans [a, b]),
ramèner le pivot en début de partition pour que la suite de l'algorithme convienne,
trier le tableau et renvoyer la position finale du pivot (comme cela était déjà le cas).
def segmenter(T,i,j):
pa = randint(i,j-1)
echange(T,pa,i)
9) Afin d'évaluer l'effet de cette modification d'algorithme avec une liste triée de 980 éléments (soit
presque triée) sur la durée d'exécution, on pourra importer le module time du paquet time.
La
fonction
time()
ainsi
importée
renvoie
le
temps
en
seconde.
En faisant la différence entre le temps après l'exécution et celui avant l'exécution, on peut
déterminer le temps mis par l'algorithme en seconde.
10) On pourra aussi comparer avec les temps nécessaires au tri par insertion.
5 Algorithme avec des arrays (tableaux numpy)
11) Tester si le tri en place est compatible avec les arrays numpy en testant vos fonctions avec ce type
de tableau. Si des modifications sont nécessaire enregistrer votre travail sous un autre nom puis
faire les modifications qui s'imposent.
12) Réécrire la fonction tri_rapide du cours 4.1 afin qu'il soit adapté à des tableaux numpy (ces
tableaux n'acceptent pas les méthodes .pop() et .append() ni la fonction len() ; on pourra
notamment utiliser l'indice du pivot pour l'éliminer de la liste à trier tout en le laissant en place.
Ressources : Damien BROIZAT (TSI2 Cannes)
Lycée Jules Ferry Cannes
Page 3 sur 3
TSI2
Téléchargement