Upload
independent
View
2
Download
0
Embed Size (px)
Citation preview
1
Algorithmique et Programmation I
Méthodes de tri
Séance 9
Année universitaire 2015/2016 – Semestre 1
2
Trier un tableau
C'est l'opération très utile qui consiste à ordonner les valeurs se trouvant dans un tableau. L'ordre peut être croissant ou décroissant.
Plusieurs méthodes ou algorithmes ont été trouvés. Ils n'ont pas tous les mêmes performances. On les compare en considérant leur vitesse et leur simplicité.
3
Tri à bulle
on parcourt le tableau à trier à du début à la fin, en comparant les
éléments consécutifs deux-à-deux tout en faisant ainsi « descendre »
vers la fin du tableau les éléments qui doivent être placés à la
fin; à la manière d'une bulle ...
si ceux-ci sont dans le bon ordre, on les laisse sinon on les inverse [
opérations notées en rouge ].
Lorsque l'on a fini de parcourir le tableau une première fois, on est sûr
d'avoir placé le dernier élément à la bonne place. On parcourt donc de
nouveau le tableau pour placer le second élément, le troisième ...
jusqu'au dernier.
4
Tri à bulle
1 2 3 0 4
1 2 3 0 4
1 2 0 3 4
i j
4
3
2
1
1
2
3
4
1
2
3
1
2
1
T[0] < T[1]
T[1] > T[2] inverser
T[2] < T[3]
T[3] > T[4] inverser
T[0] > T[1] inverser
T[1] < T[2]
T[2] > T[3] inverser
T[0] < T[1]
T[1] > T[2] inverser
T[0] > T[1] inverser
2 3 1 4 0
2 1 3 4 0
2 1 3 4 0
2 1 3 0 4
0 1 2 3 4
1 2 0 3 4
1 0 2 3 4
2 3 1 4 0
5
Tri à bulle void TriBulle (int T [ ], int N)
{
int i, j, Temp;
for (i = N-1; (i > 0); i --)
{
for (j = 1; (j <= i); j ++)
{
if (T[j-1] > T[j])
{
Temp = T[j-1];
T[j-1] = T[j];
T[j] = Temp;
}
}
}
}
C'est le moins
performant de la catégorie tris par échange/sélection
C'est un algorithme
très simple
6
Tri à bulle
On peut aussi parcourir le tableau à l’envers
en comparant les éléments consécutifs deux-à-deux tout en
faisant ainsi "remonter" vers le début du tableau les éléments
qui doivent être placés devant; à la manière d'une bulle ...
Dans une version optimisée on peut arrêter le programme si
dans une phase aucune permutation n’est effectuée
Travail à faire:
Proposer la version optimisée du tri à bulle qui parcourt le
tableau à l’envers
Tri à bulle
Travail à faire: void TriBulleOptimise (int T [ ], int N)
{
int i, j, Temp, loop =1;
i=0;
while ((i < N)&&(loop==1))
{
loop=0;
for (j = N-1; j > i; j--)
{
if (T[j] < T [j-1])
{
Temp = T[j];
T[j] = T[j-1];
T[j-1] = Temp;
loop=1; // dans cette phase, au moins une permutation est effectuée
}
}
i++;
}
}
7
8
Tri par sélection
Si le tableau contient n éléments : cet algorithme exécute n-1
étapes
Le principe du tri par sélection est de chercher à chaque étape le
minimum dans le reste du tableau et de faire l’échange avec lui
dans cette version à chaque fois qu’on trouve un élément inférieur
à l’élément courant on fait l’échange : c’est pourquoi ce n’est pas
une version optimale
input 2 3 1 4 0
i=0 1 3 2 4 0
0 3 2 4 1
i=1 0 2 3 4 1
0 1 3 4 2
i=2 0 1 2 4 3
i=3 0 1 2 3 4
9
Tri par sélection void TriSelectPasBon (int T [ ], int N)
{
int i, j, Temp, m;
for (i = 0; (i < N-1); i ++)
{
m = i;
for (j = i+1; (j < N); j ++)
{
if (T[j] < T[m])
{
m = j;
Temp = T[m];
T[m] = T[i];
T[i] = Temp;
m = i;
}
}
}
}
C'est une version
particulièrement inefficace du tri par sélection
C'est encore un
algorithme simple
10
Tri par sélection amélioré
i j m m
0
1
2
3
1
2
3
4
2
3
4
3
4
4
0
0
1
1
1
2
2
2
2
3
T[1] > T[0]
T[2] < T[0] c
T[3] > T[1]
T[4] < T[1] c
T[2] < T[1] c
T[3] > T[2]
T[4] < T[2]
T[3] > T[2]
T[4] < T[3] c
T[4] < T[3]
-
1
-
4
2
-
-
-
4
4
input 2 3 1 4 0
i=0 0 3 1 4 2
i=1 0 1 3 4 2
i=2 0 1 2 4 3
i=3 0 1 2 3 4 • Dans cette version on évite de
faire des échanges inutiles on
cherche d’abord l’indice de l’élément
minimal puis on fait l’échange
•Ici 4 échanges au lieu de 6
11
Tri par sélection amélioré void TriSelectBon (int T [ ], int N)
{
int i, j, Temp, m;
for (i = 0; (i < N-1); i ++)
{
m = i;
for (j = i+1; (j < N); j ++)
{
if (T[j] < T[m])
{
m = j;
}
}
Temp = T[m];
T[m] = T[i];
T[i] = Temp;
}
}
C'est un tri parmi
les plus lents
C'est une version
améliorée du tri par sélection
C'est encore un
algorithme simple
12
Tri par insertion
Le principe du tri par insertion est d'insérer à la n-ième itération le n-ième élément à la bonne place
Donc à chaque itération i les premiers ièmes éléments sont triés
Le problème de cet algorithme est qu'il faut parcourir le tableau trié pour savoir à quel endroit insérer le nouvel élément, puis décaler d'une case toutes les valeurs supérieures à l'élément à insérer.
input 2 3 1 4 0
Itération 1 2 3 1 4 0
Itération 2 2 3 1 4 0
Itération 3 1 2 3 4 0
Itération 4 1 2 3 4 0
Itération 5 0 1 2 3 4
13
Tri par insertion void TriInsertion (int T [ ], int N)
{
int i, j, ok;
for (i = 1; (i < N); i ++)
{
V = T[i];
j = i;
ok = (T [j-1] > V);
while ((ok) && (j>0))
{
if(T [j-1] > V)
{T [j] = T[j-1];
j = j – 1;
}
else
ok = 0;
}
T[j] = V;
}
}
C'est encore un tri
très lent
L'algorithme est
toujours simple
14
Tri par insertion
En pratique, le tableau classé est parcouru de droite
à gauche, c'est à dire dans l'ordre décroissant. Les
éléments sont donc décalés vers la droite tant que
l'élément à insérer est plus petit qu'eux..
Dés que l'élément à insérer est plus grand qu'un des
éléments du tableau triée il n'y a plus de décalage, et
l'élément est inséré dans la case laissée vacante par
les éléments qui ont été décalés.
15
Tri par insertion
i v j ok
1
2
3
4
3
1
4
0
1
2
1
0
3
4
3
2
1
0
(2 > 3) F
(3 > 1) V
(2 > 1) V
(3 < 4) F
(4 > 0) V
(3 > 0) V
(2 > 0) V
(1 > 0) V
T[1] 3
T[2] T[1]
T[1] T[0]
T[0] 1
T[3] 4
T[4] T[3]
T[3] T[2]
T[2] T[1]
T[1] T[0]
T[0] 0
input 2 3 1 4 0
i=1 2 3 1 4 0
i=2 2 3 3 4 0
2 2 3 4 0
1 2 3 4 0
i=3 1 2 3 4 0
i=4 1 2 3 4 4
1 2 3 3 4
1 2 2 3 4
1 1 2 3 4
0 1 2 3 4
0 1 2 3 4