algorithmes
Chapitre 6
Méthodes de tri
2
6 Les méthodes de tri
l Le tri est l’une des opérations les plus importantes faites par un ordinateur. Cette opération consiste à mettre une liste en ordre.
l Les applications varient de la plus simple permettant de trier en une seule opération de petites listes, à la plus sophistiquée s’appliquant aux listes de messagerie et aux dictionnaires.
l On suppose, par convention, que les éléments à trier sont des scalaires.
l Il y a deux restrictions à imposer sur les méthodes de tri qu’on va passer en revue:
– On suppose que les éléments sont triés dans l’ordre croissant. L’ordre décroissant peut être obtenu après des changements mineurs des algorithmes présentés.
– Le tri implique une comparaison des éléments avec d’autres éléments
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
3
l
Le tri par sélection consiste à mettre le plus petit élément dans position 1, ensuite le deuxième petit élément dans position 2, etc. En d'autres termes:
∀ I ∈ [1, N], mettre A[1..I] trié et ≤ A[I + 1..N]
Sélection Sort:
for (I = 1; I < N; I++)
{ /* Mettre A[1..I] trié et ≤ A[I + 1..N]
Trouver la position du plus petit élément dans A[I..N] */
Position = I;
for (J = I + 1; J ≤ N; J++)
/* Trouver la position du plus petit élément dans A[I..J] */
if (A[J] < A[Position]) Position = J;
Swap A[I] avec A[Position];
}
4
6 Les méthodes de tri
6.1.1 Le tri par sélection
l
Exemple
59 46 32 80 46 55 87 43 70 81
0 1 2 3 4 5 6 7 8 9
I
59 46 P
32 80 46 55 87 43 70 81 I = 0 Position = 2
0 1 2 3 4 5 6 7 8 9
I
59 46 P
32 80 46 55 87 43 70 81
2 1
0 3 4 5 6 7 8 9
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
5
6.1.1 Le tri par sélection
59 I
46
32 80 46 55
P
87 43 70 81 2
1
0 3 4 5 6 7 8 9
I = 1 Position = 7
59
I
46
32 80 46 55
P
87
43 70 81
2 7
0 1 3 4 5 6 8 9
I
59 46
32 43 80 46 55 87 70
P
2 7 81
0 1 3 4 5 6 8 9
I = 2 Position = 4
I
59 46
32 43 46 80 55 87 70
P
2 7 81
0 1 3 4 5 6 8 9
6
6 Les méthodes de tri
6.1.1 Le tri par sélection
I
59 46
32 80
P
46 55 87
43 70 81
2 7
0 1 3 4 5 6 8 9
I = 4 Position = 5
I
59 46
32 80
P
46 55 87
43 70 81
2 7
0 1 3 4 5 6 8 9
I = 3 Position = 7
59 P
46 32
I
80
46 55 87
43 70 81
2 7
0 1 3 4 5 6 8 9
59
P
46 32
I
80
46 55 87
43 70 81
2 7
0 1 3 4 5 6 8 9
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
7
l
Le temps nécessaire pour le tri par sélection est O(N
2), temps mesuré par la boucle interne de l’algorithme associé.
l
Space(N) est O(1) : quelques variables de contrôle de boucles et une variable temporaire.
8
6 Les méthodes de tri
6.1.2 Le tri par bulle
l
Cette technique est la plus utilisée, mais elle est indiscutablement mauvaise. Nous verrons par la suite pourquoi elle doit être évitée.
l
Idée générale: Pour trier une liste, commencer au début de la liste et comparer
chaque élément avec l’élément suivant; interchanger si nécessaire. Ensuite
recommencer au début en comparant et interchangeant. Continuer jusqu’à A[N] soit
trié. Pour éviter des comparaisons inutiles, chaque passe va jusqu’au dernier
changement de la passe précédente.
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
9
6.1.2 Le tri par bulle
BubbleSort()
{
FinalSwapPos = n;
do {
/* Mettre A[FinalSwapPos + 1..n] trié Et >= [1..FinalSwapPos] */
SwapPos = 1;
for (i = 1; i < FinalSwapPos; i++) /* Mettre A[i+1] >= A[1..i] */
if (A[i] > A[i + 1]) {
Swap A[i] avec A[i+1];
SwapPos = i;
}
FinalSwapPos = SwapPos;
}
while (FinalSwapPos != 1);
}
10
6 Les méthodes de tri
6.1.2 Le tri par bulle
l
Exemple :
59 46 32 80 46 55 87 43 70 81
0 1 2 3 4 5 6 7 8 9
59 46 32 80 46 55 87 43 70 81
0 1 2 3 4 5 6 7 8 9 46 59 32 80 46 55 87 43 70 81
0 1 2 3 4 5 6 7 8 9
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
11
59
46 32 80 46 55 87 43 70 81
0 1 2 3 4 5 6 7 8 9 46 32 59 80 46 55 87 43 70 81
0 1 2 3 4 5 6 7 8 9
59
46 32 80 46 55 87 43 70 81
0 1 2 3 4 5 6 7 8 9 46 32 59 80 46 55 87 43 70 81
0 1 2 3 4 5 6 7 8 9
12
6 Les méthodes de tri
6.1.2 Le tri par bulle
59
46 32 80 46 55 87 43 70 81
0 1 2 3 4 5 6 7 8 9 46 32 59 46 80 55 87 43 70 81
0 1 2 3 4 5 6 7 8 9
59
46 32 46 80 55 87 43 70 81
0 1 2 3 4 5 6 7 8 9 46 32 59 46 55 80 87 43 70 81
0 1 2 3 4 5 6 7 8 9
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
13
6.1.2 Le tri par bulle
59
46 32 46 55 80 43 70 81 87
0 1 2 3 4 5 6 7 8 9 32 46 59 46 55 80 43 70 81 87
0 1 2 3 4 5 6 7 8 9
...
59 46
32 46 55 80 43 70 81 87
0 1 2 3 4 5 6 7 8 9 32 46 59 46 55 80 43 70 81 87
0 1 2 3 4 5 6 7 8 9
14
6 Les méthodes de tri
6.1.2 Le tri par bulle
•
Si la liste est déjà ordonnée, BestTime(N) = O(N).
(une seule passe de N-1 comparaisons)
• Si la liste est triée par ordre décroissant, WorstTime(N) = O(N²).
• Time(N) = O(N²). (en moyenne)
•
Noter que le grand nombre de Swap ≈ N²/8 versus N-1 dans le tri par sélection.
•
Space = O(1).
•
BubbleSort est meilleur que SélectionSort seulement lorsque les éléments
sont presque triés.
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
15
l
Pour chaque valeur de I ∈[2, N], on commence avec A[1..I-1] déjà trié et on insère A[I] dans sa propre position tel que A[1..I] soit trié.
l
La recherche de la position adéquate est accomplie par un balayage de droite vers la gauche commençant à la position I.
16
6 Les méthodes de tri
6.1.3 Le tri par insertion
InsertionSort() {
for (i=2; i <= n; i++) { /* Mettre A[1..i] trié */
j = i;
temporary = A[j];
/* Ouvrir la position correcte pour temporary dans A[1..i] */
while (j > 1 && A[j-1] > temporary) { /* A[J..I] trié */
/* Mettre A[1..j - 1] trié; temporary <= A[j..i] trié */
A[j] = A[j-1];
j--;
}
A[j] = temporary;
}
} /* Fin de InsertionSort */
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
17
6.1.3 Le tri par insertion
l
Exemple :
59 46 32 80 46 55 87 43 70 81
0 1 2 3 4 5 6 7 8 9
18
6 Les méthodes de tri
6.1.3 Le tri par insertion
59 46 32 80 46 55 87 43 70 81 i = 1 Temp = 46
0 1 2 3 4 5 6 7 8 9
j = 1
59
46
32 80 46 55 87 43 70 81
0 591 2 3 4 5 6 7 8 9
i = 1 Temp = 46 j = 0
32 80 46 55 87 43 70 81
0 591 2 3 4 5 6 7 8 9
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
19
46 32 80 46 55 87 43 70 81
0 591 2 3 4 5 6 7 8 9
i = 2 Temp = 32 j = 2
46
32
80 46 55 87 43 70 81
0 591 592 3 4 5 6 7 8 9
i = 2 Temp = 32 j = 1
46 80 46 55 87 43 70 81
0 461 592 3 4 5 6 7 8 9
i = 2 Temp = 32 j = 0
80 46 55 87 43 70 81
0 461 592 3 4 5 6 7 8 9
20
6 Les méthodes de tri
6.1.3 Le tri par insertion
32 i = 3 Temp = 80 j = 3
80 46 55 87 43 70 81
0 461 592 3 4 5 6 7 8 9
32 80 46 55 87 43 70 81
0 461 592 3 4 5 6 7 8 9
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
21
6.1.3 Le tri par insertion
32 i = 4 Temp = 46 j = 4
80
46
55 87 43 70 81
0 461 592 3 4 5 6 7 8 9
32 80 46 55 87 43 70 81
0 461 592 3 4 5 6 7 8 9 80
32 i = 4 Temp = 46 j = 3
55 87 43 70 81
0 461 592 593 804 5 6 7 8 9 32
i = 4 Temp = 46 j = 2
55 87 43 70 81
0 461 2 593 804 5 6 7 8 9
22
6 Les méthodes de tri
6.1.3 Le tri par insertion
46 32 i = 5 Temp = 55 j = 5
55 87 43 70 81
0 461 2 593 804 5 6 7 8 9
46
32 55 87 43 70 81
0 461 2 593 804 5 6 7 8 9 80
46 32 i = 5 Temp = 55 j = 4
87 43 70 81
0 461 2 593 594 805 6 7 8 9 32 46
i = 5 Temp = 55 j = 3
87 43 70 81
0 461 2 3 594 805 6 7 8 9
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
23
•
Si la liste est déjà ordonnée, BestTime = O(N)
•
Si la liste est triée par ordre décroissant, WorsTime (N) = O(N
2)
•
Time(N) = O(N
2)
•
Space(N) = O(1)
•
InsertionSort est plus rapide que la BubbleSort dans les deux cas: Average et WorstCase.
24
6 Les méthodes de tri
6.2 Méthodes de tri rapide
l
À l’inverse des méthodes précédentes où Time = O(N
2), dans chaque méthode de tri présentée dans cette section
Time = de O(N logN). On montrera comment la différence est grande entre un algorithme O(N logN) et un algorithme O(N
2).
l
Dans cette section, chaque méthode de tri est de O(N log N)
seulement. Pour certaines WorstTime est aussi O(N log N), alors
que pour d’autres WorstTime est O(N
2).
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
25
6.2.1 Tri par arbre
l
Les éléments de la liste sont insérés, un par un, dans un arbre de tri binaire. Un arbre de tri binaire est semblable à un arbre de
recherche binaire, à l’exception que les duplications sont permises.
l
Suivant l’algorithme d’insertion dans les arbres de recherche binaire, un élément égale à l’élément de la racine devrait être inséré dans le sous arbre droit.
l
Après la construction de l’arbre de tri binaire, les éléments obtenus par un parcours “ inorder ” sont alors stockés triés dans la liste A.
26
6 Les méthodes de tri
6.2.1 Tri par arbre
TreeSort() {
Tree.Initialize;
for (i = 1; i <= N; i++) Tree_Insert(A[i]);
i = O;
Tree.TraverseInOrder(BackToA);
} /* Fin de TreeSort */
BackToA(Item) {
A[i++] = Item;
} /* Fin de BackToA */
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
27
Exemple : A = [59 46 32 80 46 55 87 43 70 81]
Après insertion dans l’arbre:
Finalement, après le parcours "inorder" de l’arbre : A = [32 43 46 46 55 59 70 80 81 87]
46
43 55
46 32
81 80
87 70
59
28
6 Les méthodes de tri
6.2.1 Tri par arbre
l Pour simplifier, on suppose qu’il n’y pas de duplication d’éléments.
–
Si les éléments sont déjà triés selon un ordre croissant ou décroissant, l’arbre sera alors organisé en chaîne.
WorstTime = O(N²)
–
Dans les meilleurs cas, l’arbre tend vers une organisation parfaitement équilibrée, d’où :
BestTime = O(N log N)
AverageTime = O(N log N)
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
29
6.2.2 Tri par fusion
l
C’est une approche récursive Top-Down, dérivée de l’algorithme de division dichotomique. Cependant l’algorithme poursuit la division de la liste en deux jusqu’à avoir la taille de liste égale à 1 et ensuite il fusionne les deux parties en les triant.
l
En divisant le sous-algorithme de fusion de deux sous-listes, on obtient facilement le sous algorithme SplitAndMerge:
30
6 Les méthodes de tri
6.2.2 Tri par fusion
SplitAndMerge(first, last) {
if (first < last) {
middle = (first + last) / 2;
SplitAndMerge(first, middle);
SplitAndMerge(middle + 1, last);
Merge(first, middle, middle + 1, last);
} }
l
Le sous-algorithme de fusion, Merge, fusionne deux sous-listes triées en une sous-
liste triée. Les éléments sont déplacés, un par un, dans un tableau temporaire et
ensuite sont copiés dans A. Le sous-algorithme
Mergeest alors décrit comme suit:
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
31
Merge(LeftFirst, LeftLast, RightFirst, RightLast) /* Précondition:
A[LeftFirst..LeftLast] est trié;
A[RightFirst..RightLast] est trié;
LeftFirst <= LeftLast=RightFirst-1;
RightFirst <= RightLast; */
{
I = LeftFirst;
J = RightFirst;
K = 1;
while (I <= LeftLast &&
J <= RightLast) { /* Déplacer les plus petits K éléments de [LeftFirst..RightLast]
dans Temps [1..K] */
if (A[I] <= A[J]) {
Temp[K] = A[I];//(corriger) I++; K++;
} else {
Temp[K] = A[J];
J++; K++;
} }
32
6 Les méthodes de tri
6.2.2 Tri par fusion
/* Déplacer le reste de
A[LeftFirst..LeftLast], si ∃ dans Temp */
while (I <= LeftLast) { Temp[K] = A[I];
I++; K++;
}
/* Déplacer le reste de
[RightFirst..RightLast], si ∃ dans Temp */
while (J <= RightLast) { Temp[K] = A[J];
J++; K++;
}
/* Déplacer Temp[1..K-1] dans A[LeftFirst..RightLast] */
for(I = 1; I < K; I++)
A[I - 1 + LeftFirst] = Temp[I];
} /* Fin de Merge */
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
33
6 Les méthodes de tri
6.2.2 Tri par fusion
Split(6, 10)55 87 43 70 81
Split(1, 3) 59 46 32
Split(1, 2) 59 46
Split(3, 3) 32
Split(1, 5) 59 46 32 80 46
Split(4, 5) 80 46
...
Split(1, 1) ...
59 Split(2, 2)
46
Merge(1, 1, 2, 2) 46 59
Merge(1, 2, 3, 3) 32 46 59
Split(4, 4) 80
Split(5, 5) 46
Merge(4, 4, 5, 5) 46 80
Merge(1, 3, 4, 5) 32 46 46 59 80
Merge(...) 43 55 70 80 87
Merge(1, 5, 6, 10) 32 43 46 46 55 59 70 80 81 87
...
...
...
34
6 Les méthodes de tri
6.2.2 Tri par fusion
l
WorstTime(N), BestTime(N) et Time(N) sont tous O(N logN);
l
Space = O(N), à cause du tableau temporaire.
l
Remarque : trouver le point milieu dans une liste chaînée nécessite
un temps O(N) tandis que dans une structure de données contiguë
(comme un tableau) trouver le point milieu nécessite un temps de
O(1).
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
35
l
On peut développer une version itérative de MergeSort en adoptant une approche bottom-up:
•
Dans la première passe, fusionner les paires des singletons consécutifs dans des doubletons triés.
•
Dans la seconde passe, fusionner les paires de doubletons consécutifs déjà triés dans des quadrupletons triés.
•
Dans la troisième passe, fusionner les paires de quadrupletons consécutifs déjà triés dans des octupletons triés.
•
Continuer le processus jusqu’à A[1..N] soit trié.
36
6 Les méthodes de tri
6.2.2 Tri par fusion
MergeSort() /* Itératif */
{
Size = 1;
while (Size < N) {
/* invariant de boucle: A[1..Size], A[Size+1..2*Size] sont tous triés */
LeftFirst = 1;
while (LeftFirst + Size <= N) {
/* Invariant de boucle: toutes les paires de sous-listes dans
A[1..LeftFirst] de taille 2*Size sont triés */
/*Calcul des limites d'une sous-liste*/
LeftLast = LeftFirst + Size - 1;
RightFirst = LeftLast + 1;
if ((RightFirst + Size - 1) > N) RightLast = N;
else
RightLast = RightFirst+Size-1;
Merge(LeftFirst, LeftLast, RightFirst, RightLast);
LeftFirst = RightLast + 1;
}
Size = Size * 2;
}
} /* Fin de Merge */
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
37
6.2.2 Tri par fusion
59 46 32 80 46 55 87 43 70 81
59 46 32 80 46 55 87 43 70 81
46 59 32 80 55 46 43 87 70 81
32 46 59 80 43 46 55 87 70 81
32 43 46 46 55 59 80 87 70 81
32 43 46 46 55 59 70 80 81 87
38
6 Les méthodes de tri
6.2.2 Tri par fusion
l
On remarquer encore que
–
Time, BestTime et WorstTime sont O(NlogN)
–
Space est de O(N).
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
39
l
Cette méthode de tri est basée sur les arbres en épi, et fonctionne comme suit:
1. Ayant une liste Ade Néléments, on doit les insérer en premier dans un arbre binaire complet et l’organiser en épi.
2. Ensuite, on interchange (Swap) le premier et le dernier éléments et par conséquent, on aura mis le plus grand élément dans la position N(ce qu’on cherchait).
3. La phase suivante est d’appliquer le ReHeapà l’arbre de la position 1 à la position N-1.
4. On répète ce processus de Swap et ReHeapjusqu’à ce que les éléments de l’arbre soient triés.
5. Finalement en parcourant l’arbre, on peut remplir de nouveau la listeAqui devient triée.
l
Les méthodes Insert, Swap et ReHeap ont été développées dans la section concernant les arbres en épi. Tout ce qui reste à développer est la construction d’un épi partant d’un arbre binaire complet.
40
6 Les méthodes de tri
6.2.3 Tri par épi
HeapSort()
{ /* Insérer A[1..n] dans un arbre binaire complet */
Initialize;
for (i = 1; i <= n; i++) InsertLast(A[i]);
/* Organiser l'arbre en épi */
for (i = n / 2; i >= 1; i--) ReHeap(i, n);
/* Mettre les éléments, du plus grand au plus petit, dans les positions n, n-1, ..., 1 dans l'arbre */
for (i = n; i > 1; i--) { Swap(1, i);
ReHeap(1, i - 1);
}
/*Copier les éléments dans la liste A en parcourant l'arbre */
for (i = 1; i <= n; i++)
Retrieve(A[i], i);
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
41
6.2.3 Tri par épi
l
Exemple :
–
Nous avons la liste A = [59 46 32 80 46 55 87 43 70 81].
–
Après l’application de la première boucle, on aura l’arbre binaire complet suivant (qui n’est pas organisé en épi)
46
70
32 87 55
59
81 43
46 80
42
6 Les méthodes de tri
6.2.3 Tri par épi
l
Nous obtenons ensuite l’arbre en épi suivant :
l
Après l’appel de Swap(1, 10) et ReHeap(1, 9) on a l’arbre suivant qui est organisé en épi de 1 à 9 :
81
70
59
32 55
87
46 43
46 80
80
46
59
32 55
81
87 43
46 70
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
43
l
Maintenant on fait l’appel de Swap(1, 9) et ReHeap(1, 8), ce qui donne :
l
Après l’appel de Swap(1, 10) et ReHeap(1, 9) on a l’arbre suivant qui est organisé en épi de 1 à 9 :
70
81
59
32 55
80
87 43
46 46
43
81
46
70 59
32
87 80
55 46
44
6 Les méthodes de tri
6.2.3 Tri par épi
l
L’analyse de HeapSort dépend des analyses des méthodes InsertLast, ReHeap, Swap et Retreive.
–
WorstTime = O(NlogN)
–
AverageTime = O(N log N)
–
BestTime = O(N log N)
–
Space = O(1)
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
45
6.2.4 Tri rapide
l
Le tri rapide est l’une des méthodes les plus efficaces et les plus utilisées.
l
Principalement, l’algorithme du tri rapide est une simple application du principe “diviser pour conquérir”.
l
Pour appliquer cet algorithme sur un tableau A, on doit d’abord partitionner le tableau en un sous-tableau gauche et un sous-tableau droit, tels que
chaque élément du sous-tableau gauche <= tout élément du sous-tableau droit.
l
Ensuite on applique de nouveau l’algorithme aux sous-tableaux gauche et droit, ainsi on aura trié le tableau A.
l
Étant donné que la dernière phrase peut être implantée par deux appels récursifs de QuickSort, on va se concentrer d’avantage sur la phase de partitionnement.
46
6 Les méthodes de tri
6.2.4 Tri rapide
l
Le partitionnement commence en sélectionnant un élément dans A[1..N].
L’élément choisi est nommé pivot, soit l’élément du milieu du tableau.
l
Si on commence avec le tableau A[1..14] suivant:
19 56 28 101 47 16 39 54 27 18 92 45 61 72
l
Le pivot est l’élément 39, milieu du tableau. Maintenant, on veut déplacer tous les éléments inférieurs à 39 à gauche du 39 et tous les éléments plus grand que 39 à droite du 39. Les éléments égaux à 39 peuvent être à gauche ou à droite.
l
Les tailles des deux parties résultantes ne sont pas nécessairement égales.
.
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
47
l
Étape 1 : Nous avons :
l
Étape 2 : UpCounter est incrémenté et s’arrête à 56 DownCounter est décrémenté et s’arrête à 18
19 56 28 101 47 16 39 54 27 18 92 45 61 72 Pivot
UpCounter
DownCounter
19 56 28 101 47 16 39 54 27 18 92 45 61 72 Pivot
UpCounter
DownCounter
48
6 Les méthodes de tri
6.2.4 Tri rapide
l
Étape 3 : 18 et 56 sont interchangés
UpCounter est incrémenté et DownCounter est décrémenté
l
Étape 4 : UpCounter est incrémenté et s’arrête à 101 DownCounter est décrémenté et s’arrête à 27
19 18 28 101 47 16 39 54 27 56 92 45 61 72 Pivot
UpCounter
DownCounter
19 18 28 101 47 16 39 54 27 56 92 45 61 72 Pivot
UpCounter
DownCounter
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
49
6.2.4 Tri rapide
l
Étape 5 : 27 et 101 sont interchangés
UpCounter est incrémenté et DownCounter est décrémenté
l
Étape 6 : UpCounter est incrémenté et s’arrête à 47 DownCounter est décrémenté et s’arrête à 39
19 18 28 27 47 16 39 54 101 56 92 45 61 72 Pivot
UpCounter
DownCounter
19 18 28 27 47 16 39 54 101 56 92 45 61 72 Pivot
UpCounter DownCounter
50
6 Les méthodes de tri
6.2.4 Tri rapide
l
Étape 7 : 37 et 49 sont interchangés
UpCounter est incrémenté et DownCounter est décrémenté
l
Étape 8 : UpCounter est incrémenté et s’arrête à 47 DownCounter reste à 16
19 18 28 27 39 16 47 54 101 56 92 45 61 72 Pivot
UpCounter DownCounter
19 18 28 27 39 16 47 54 101 56 92 45 61 72 Pivot
UpCounter DownCounter
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
51
l
Puisque UpCounter est supérieur à DownCounter et étant donné que chaque élément a été comparé à l’élément pivot, aucun « swap » n’est alors effectué.
l
La partition gauche va de 1 à 6 (du début à DownCounter)
l
La partition droite va de 7 à 14 (de UpCounter à la fin)
52
6 Les méthodes de tri
6.2.4 Tri rapide
l
Étape 1 de la partition A[1..6] : Le pivot est 28.
l
Étape 2 : UpCounter est incrémenté et s’arrête à 28 DownCounter est décrémenté et s’arrête à 16
19 18 28 27 39 16 Pivot
UpCounter
DownCounter
19 18 28 27 39 16 Pivot
UpCounter
DownCounter
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
53
6.2.4 Tri rapide
l
Étape 3 : 28 et 16 sont interchangés
UpCounter est incrémenté et DownCounter est décrémenté
l
Étape 4 : UpCounter est incrémenté et s’arrête à 39 DownCounter est décrémenté et s’arrête à 27
19 18 16 27 39 28 Pivot
UpCounter DownCounter
19 18 16 27 39 28 Pivot
UpCounter DownCounter
54
6 Les méthodes de tri
6.2.4 Tri rapide
l
Puisque UpCounter est supérieur à DownCounter et étant donné que chaque élément a été comparé à l’élément pivot, aucun « swap » n’est alors effectué.
l
La partition gauche va de 1 à 4 (du début à DownCounter)
l
La partition droite va de 5 à 6 (de UpCounter à la fin)
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
55
l
Étape 1 de la partition A[1..4] : Le pivot est 18.
l
Étape 2 : UpCounter est incrémenté et s’arrête à 19 DownCounter est décrémenté et s’arrête à 16
19 18 16 27 Pivot
UpCounter
DownCounter
19 18 16 27 Pivot
UpCounter DownCounter
56
6 Les méthodes de tri
6.2.4 Tri rapide
l
Étape 3 : 19 et 16 sont interchangés
UpCounter est incrémenté et DownCounter est décrémenté
l
Étape 4 : UpCounter est incrémenté et s’arrête à 19 DownCounter est décrémenté et s’arrête à 16
16 18 19 27 Pivot
UpCounter DownCounter
16 18 19 27 Pivot
UpCounter DownCounter
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
57
6.2.4 Tri rapide
l
Le sous-tableau gauche consiste en A[1..1], et le sous-tableau droit consiste en A[3..4].
l
Étant donné que l’élément A[2] est déjà à sa place, donc on ne s’intéresse plus à cet élément. A[1..1] est déjà trié.
l
Il suffit de “QuickSort” A[3..4], A[5..6] et A[7..14].
58
6 Les méthodes de tri
6.2.4 Tri rapide
QuickSort() {
DoQuickSort(1, n);
} /* Fin de QuickSort */
DoQuickSort(first, last) {
if (last > first) {
Partition(first, last, leftLast, rightFirst);
DoQuickSort(first, leftLast);
DoQuickSort(rightFirst, last);
}
} /* Fin de DoQuickSort */
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
59
Partition(first, last, leftLast, rightLast) {
UpCounter = first;
DownCounter = last;
Pivot = A[(first + last) / 2];
/* Mettre A[first .. UpCounter - 1] <= Pivot <=
A[DownCounter + 1.. last] && UpCounter > DownCounter*/
do{
while (A[UpCounter] < Pivot) UpCounter++;
while (A[DownCounter] > Pivot) DownCounter --;
if (UpCounter <=DownCounter)
Swap A[UpCounter] avec A[DownCounter] et avancer les compteurs;
} while (!(UpCounter > DownCounter));
leftLast = DownCounter;
rightFirst = UpCounter;
} /* Fin de Partition */
60
6 Les méthodes de tri
6.2.4 Tri rapide
l
D’après le phénomène de partitionnement on peut voir ce processus comme créer un arbre de tri binaire
l BestTime
est O(N logN)
l WorstTime
est O(N
2)l AverageTime
est O(N logN)
l BestSpace, Space
et WorstSpace est O(N), selon la hauteur de l’arbre de tri ainsi créé.
(space =O(N) pour les variables qui doivent contenir les limites des intervalles)
GPA665 - Hiver 2002 © Mohamed Cheriet, ing., Ph. D.
61
6.2.4 Tri rapide
l
Étant donné que QuickSort est largement utilisé, il est intéressant d’améliorer son efficacité. On propose deux améliorations:
– Ne pas utiliser QuickSortpour de petits tableaux. La machinerie pour partitionner les sous- tableaux de deux ou trois éléments consomme plus de temps que d’appliquer le tri direct.
Cependant, on doit trier avec QuickSortun sous-tableau que si sa taille est supérieure à un certain seuil C ( par exemple 3). On doit alors remplacer:
if (last > first) par
if (last - first >= 3)
DoQuickSort
va être appliquer alors aux sous-tableaux ayant comme taille >=4.
62
6 Les méthodes de tri
6.2.4 Tri rapide
– Après avoir accomplie l’exécution de QuickSortavec Seuil, A[1..N] ne sera pas complètement trié, mais “semi-trié”, i.e A[1..N] consistera en Ksegments tel que K > 0:
A[1..N1], A[N1+1...N2], A[N2+1..N3], ..., A[Nk-1...N]
∀J ∈[1, K-1], tous les éléments dans le segmentJsont inférieurs ou égaux à tous les éléments du segment J+1. La taille de chaque segment est au plus égale au Seuil C.
– Pour accomplir ces semi-tris, ça nécessite O(NlogN). Pour accomplir le tri, on applique le tri par Insertion amélioré à A[1..N]. On rappelle que cette opération nécessite O(N) pour un tableau trié ou presque trié.
*Time(N)pour cette version améliorée est O(N logN).