Vous êtes sur la page 1sur 17
Les Les algorithmes algorithmes de de tri tri • Objectif : réarranger les éléments de

LesLes algorithmesalgorithmes dede tritri

• Objectif : réarranger les éléments de manière à ce que leurs clés soient ordonnées

• utilisés pour trier des fichiers ou des clés en mémoire

• La clé est un élément de l’objet considéré

• Tri interne ou tri externe

• Tri avec des tableaux ou tri avec des listes chaînées

AlgorithmesAlgorithmes etet StructuresStructures dede DonnDonnééeses

Wurtz Jean-Marie

Université Louis Pasteur Wurtz@igbmc.u-strasbg.fr

LesLes algorithmesalgorithmes dede tritri (2)(2)

Borne gauche Borne droite
Borne gauche
Borne droite

Algorithme ?

•Algorithme de tri par insertion •Algorithme de tri par sélection •Algorithme de tri par bulle (bubble sort)

Coût d’un algorithmele: nombre de comparaisons

LesLes clclééss desdes éélléémentsments àà triertrier

• L’élément : autre chose que des entiers, des flottants

• Manipulation de références

• Les lettres du mot « EXAMPLE »

: autre chose que des entiers, des flottants • Manipulation de références • Les lettres du
: autre chose que des entiers, des flottants • Manipulation de références • Les lettres du

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

ImplImpléémentationmentation ggéénnéériquerique

class Sort { static boolean less(ITEM v, ITEM w) { return v.less(w); } static void exch(ITEM[] a, int i, int j) { ITEM t = a[i]; a[i] = a[j]; a[j] = t;

}

static void compExch(ITEM[] a, int i, int j) { if (less(a[j], a[i])) exch (a, i, j);

}

static void sort(ITEM[] a, int l, int r) { example(a, l, r); } static void example(ITEM[] a, int l, int r) {

}

}

for (int i = l+1; i <= r; i++) for (int j = i; j > l; j--) compExch(a, j-1, j);

Double boucle

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

AlgorithmeAlgorithme dede tritri stablestable

1) Tri d’après la première clé (les chaînes de caractères)

2) Puis tri d’après la deuxième clé (entiers)

– 2.1 ne conserve pas l’ordre du premier tri

– 2.2 conserve l’ordre

1 2.1

la deuxième clé (entiers) – 2.1 ne conserve pas l’ordre du premier tri – 2.2 conserve
la deuxième clé (entiers) – 2.1 ne conserve pas l’ordre du premier tri – 2.2 conserve

2.2

la deuxième clé (entiers) – 2.1 ne conserve pas l’ordre du premier tri – 2.2 conserve
la deuxième clé (entiers) – 2.1 ne conserve pas l’ordre du premier tri – 2.2 conserve

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

UneUne structurestructure dede donndonnééee abstraiteabstraite pourpour ITEMITEM

interface ITEM { boolean less(ITEM v); }

class myItem implements ITEM // interface SDA { // implémentation et les membres privés sont cachés public boolean less(ITEM) void read() void rand() public String toString()

}

CoCoûûtt ddunun algorithmealgorithme dede tritri

• Nombre de comparaisons et d’échanges

– Les algorithmes en N 2 pour trier N éléments

• Tri par insertion, par sélection, par bulle

– D’autres algorithmes trient en NlogN, moins bien adaptés pour N petits ou des situations particulières

– « Shell sort » coût en N 3/2

• ShellSort et QuickSort

• Compromis entre le temps d’exécution et l’espace mémoire

• Réduire le nombre d’instruction dans la double boucle

TriTri parpar sséélectionlection (2)(2)

• Pos. 1(A) : recherche du plus petit, c’est A;

• Pos. 2(S) : recherche du plus petit, c’est A; échange de S et A

• Pos. 3(O) : recherche du plus petit, c’est E; échange de O et E

Le programme

c’est A; échange de S et A • Pos. 3(O) : recherche du plus petit, c’est

TriTri parpar sséélectionlection (1)(1)

• Le principe :

– trouver l’élément le plus petit dans le tableau et le mettre à la première position

– On échange l’élément à la mauvaise position avec le plus petit élément

• Appliquer l’algorithme au sous-tableau non trié

• Un exemple :

la mauvaise position avec le plus petit élément • Appliquer l’algorithme au sous-tableau non trié •

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

TriTri parpar sséélectionlection (3)(3)

static void selection(ITEM[] a, int l, int r) { for (int i = l; i < r; i++){ int min = i; for (int j = i+1; j <= r; j++) if (less(a[j], a[min])) min = j; exch(a, i, min);

}

}

Coût :

•N-1 échanges •N(N-1)/2 comparaisons Donc en O(N 2 )

TriTri parpar sséélectionlection (4)(4)

• L’algorithme est-il stable?

lection lection (4) (4) • L’algorithme est-il stable? static void selection(ITEM[] a, int l, int r)

static void selection(ITEM[] a, int l, int r) { for (int i = l; i < r; i++){ int min = i; for (int j = i+1; j <= r; j++) if (less(a[j], a[min])) min = j; exch(a, i, min);

}

}

TriTri parpar insertioninsertion (1)(1)

• Le principe :

– on considère chaque élément de la gauche vers la droite et on l’insert à la bonne place parmi les éléments déjà triés

• Un exemple :

on l’insert à la bonne place parmi les éléments déjà triés • Un exemple : •

• Approche simple mais inefficace

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

TriTri parpar sséélectionlection :: exempleexemple

1

2

3

4

5

6

7

8

9 10

1

2

4

2

4

1

4

2

3

3

Ad Bl Br Ja Jo Sm Th Wa Wh Wi

4 1 4 2 3 3 Ad Bl Br Ja Jo Sm Th Wa Wh Wi

j=2 1

1 4 2 3 3 Ad Bl Br Ja Jo Sm Th Wa Wh Wi j=2

Ad Sm Ja Bl Wa Wh Wi Jo Br Th

Ad Bl Br Ja Jo Sm Th Wa Wh Wi

j=3 1

Ad Sm Br Ja Jo Bl Th Wa Wh Wi

j=4 1

Ad Sm Ja Br Jo Bl Th Wa Wh Wi

j=5 1

Ad Sm Ja Bl Jo Br Th Wa Wh Wi

j=6 1

Ad Sm Ja Bl Wa Br Th Jo Wh Wi

j=7 1

Ad Sm Ja Bl Wa Wh Th Jo Br Wi

j=8 1

TriTri parpar insertioninsertion (2)(2)

1. Compare S a A

2. Compare R successivement aux 2 éléments précédents

3. Compare T aux 3 éléments précédents
4. …

La partie inférieure est ordonnée, la partie supérieure reste à trier

Le programme

3 éléments précédents 4. … La partie inférieure est ordonnée, la partie supérieure reste à trier
 

TriTri parpar insertioninsertion (3)(3)

 

static void insertion1 (double[] a, int l, int r) { for (int i = l+1; i <= r; i++) for (int j = i; j > l; j--) compExch(a, j-1, j);

Coût :

•N(N-1)/2 comparaisons

et échanges

}

Donc en O(N 2 )

 

static boolean less(ITEM v, ITEM w) { return v.less(w);

}

static void exch(ITEM[] a, int i, int j) {

 

ITEM t = a[i]; a[i] = a[j]; a[j] = t;

 

}

t

= a[j]; a[j] = a[j+1]; a[j+1] = t Suivi de :

static void compExch(ITEM[] a, int i, int j) if (less(a[j], a[i])) exch (a, i, j);

{

t

= a[j-1]; a[j-1] = a[j]; a[j] = t

}

TriTri parpar insertioninsertion (5)(5)

• L’algorithme est-il stable?

insertion (5) (5) • L’algorithme est-il stable? static void insertion(ITEM[] a, int l, int r) {

static void insertion(ITEM[] a, int l, int r) { int i; for (i = r; i > l; i--) compExch(a, i-1, i); for (i = l+2; i <= r; i++){ int j = i; ITEM v = a[i]; while (less(v, a[j-1])) { a[j] = a[j-1]; j--;

}

}

}

a[j] = v;

static void insertion1 (double[] a, int l, int r) { for (int i = l+1; i <= r; i++)

for (int j = i; j > l; j--) compExch(a, j-1, j);

TriTri parpar insertioninsertion (4)(4)

}

static void insertion(ITEM[] a, int l, int r) { int i; for (i = r; i > l; i--) compExch(a, i-1, i); for (i = l+2; i <= r; i++){ int j = i; ITEM v = a[i]; while (less(v, a[j-1])) { a[j] = a[j-1]; j--;

}

a[j] = v;

1.Sortir plus tôt de la boucle interne

2.Une sentinelle

3.Les échanges :

t=a[j]; a[j]=a[j-1]; a[j-1]=t; suivi de t=a[j-1]; a[j-1]=a[j-2]; a[j-2]=t;

}

}

2.Une sentinelle 3.Les échanges : t=a[j]; a[j]=a[j-1]; a[j-1]=t; suivi de t=a[j-1]; a[j-1]=a[j-2]; a[j-2]=t; } }

TriTri parpar insertioninsertion :: exempleexemple

Tri Tri par par insertion insertion : : exemple exemple   1 2 3 4 5
 

1

2

3

4

5

6

7

8

9 10

 

3

3

Wh Wi

 

Bl Br Ja Jo Wa Th Wh Wi

3

3

l=3,4

 

5

 

4

2

4

3

3

Ad Sm Bl Ja Br Jo Wa Th Wh Wi

l=6,7

7

5   4 2 4 3 3 Ad Sm Bl Ja Br Jo Wa Th Wh

4

3

3

Ad Sm Bl Ja Wa Br Jo Th Wh Wi

L=8,9

9

5   4 2 4 3 3 Ad Sm Bl Ja Br Jo Wa Th Wh

10

Insertion

Selection

CaractCaractééristiquesristiques dynamiquesdynamiques desdes algorithmesalgorithmes dede tritri (1)(1)

• Image de droite : tri par sélection,

– pas de test en avant par rapport à la position courante

• Image de gauche : tri par insertion

– pas de test en arriere la position courant

• Valeurs aléatoires

• Tableau représenté par le couple (i, a[i]);

• Tableau non trié : répartition aléatoire des couples

• Une fois trié on obtient une diagonale

couple (i, a[i]); • Tableau non trié : répartition aléatoire des couples • Une fois trié

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

TriTri parpar bullebulle (2)(2)

1. On commence à droite par E, qui

est

décalée jusqu’à la position de

A

2. Puis L est décalée juste avec E

3. Puis P est sélectionné, il est plus grand que M, qui prend le relais,

M

est plus grand que L, L prend

le

relais, L est plus grand que G,

G

est le plus petit élément

4. ….

« Bubble sort » trie le sous tableau gauche comme le tri par

sélection

Le programme

le plus petit élément 4. …. « Bubble sort » trie le sous tableau gauche comme

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

TriTri parpar bullebulle (1)(1)

• Le principe :

– on considère chaque élément de la droite vers la gauche et on le compare à son voisin de gauche

– Si nécessaire on l’échange

– L’algorithme s’arrête quand tous les éléments sont triés

• Un exemple :

– Si nécessaire on l’échange – L’algorithme s’arrête quand to us les éléments sont triés •

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

static void bubble(ITEM[] a, int l, int r) { for (int i = l; i < r; i++) for (int j = r; j > i; j--) compExch(a, j-1, j);

}

TriTri parpar bullebulle (3)(3)

static void selection(ITEM[] a, int l, int r) { for (int i = l; i < r; i++){ int min = i; for (int j = i+1; j <= r; j++) if (less(a[j], a[min])) min = j; exch(a, i, min);

}

}

Coût ?

•A l’étape i : N-i comparaisons et échanges

•Coût en O(N 2 )

•L’algorithme le plus lent

•Si le fichier est déjà trié?

EtudeEtude empiriqueempirique desdes algorithmesalgorithmes dede tritri

x2 x4 x2 x4
x2
x4
x2
x4

ComportementComportement desdes algorithmesalgorithmes dede tritri

• Données à trier en fonction de l’angle

• Les algorithmes :

– A : tri par insertion

– B : tri par sélection

– C : tri par bulle

• En grisé les éléments qui ne sont pas modifiés

• En foncé, ceux qui sont modifiés à l’étape courante

AB

C

En grisé les éléments qui ne sont pas modifiés • En foncé, ceux qui sont modifiés

Copyright "Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

22 algorithmesalgorithmes dede tritri àà bullebulle

• Image de gauche : tri par bulle standard

– se comporte comme un tri par sélection (ne revient jamais en arrière)

– chaque étape met un élément à la bonne place

• Image de droite : Tri à bulle amélioré

– alterne entre droite et gauche

– algorithme du shaker sort

place • Image de droite : Tri à bulle amélioré – alterne entre droite et gauche

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

PerformancePerformance dede cesces algorithmesalgorithmes

• Tri par sélection : N 2 /2 comparaisons et N échanges

• Tri par insertion : N 2 /4 comparaisons et N 2 /4 échanges, au pire N 2 /2

• Tri par bulle : N 2 /2 comparaisons et N 2 /2 échanges en moyenne et au pire

• A noter que si un fichier est déjà trié le coût du tri par insertion est linéaire alors que les versions tri par bulle et tri par sélection sont quadratiques !!!

AlgorithmeAlgorithme dede tritri shakershaker

Rechercher en même temps le minimum et le maximum à chaque étape

 

A

S

O

R

T

I N

G

E X

A M

P L E

A

S

O

R

T

I N

G

E E

A M

P L X

A vous ?

S O R T I N G E X A M P L E A S

AlgorithmeAlgorithme dede tritri shakershaker

static void shaker(ITEM[] a, int l, int r){ for (int i=l, k=r-1; i < k; i++, k--) { int min = i; int max = i; for (int j = k; j > i ; j--) { if (a[j] < a[min]) min = j; else if (a[j] > a[max]) max = j;

}

Exch(a, min, i); if (max == i) max = min; Exch(a, max, k);

}

}

ExerciceExercice :: tritri shakershaker

AlgorithmesAlgorithmes dede tritri performantperformant

• ShellSort

• QuickSort

ShellShell SortSort

• S’inspire du tri par insertion :

– échange 2 éléments consécutifs : écart de 1 entre les 2 éléments

• Si l’élément, avec la plus petite clef, est en dernière position il faut N étapes pour amener la clef à la bonne position

A
A

A

faut N étapes pour amener la clef à la bonne position A • Le tri par

• Le tri par insertion est lent car on n’échange que des éléments qui adjacents

• Shell sort : permet des échanges entre des éléments dont l’écart est plus grand que 1

• La méthode Shellsort?

TriTri parpar sautsaut

• 4-tri de 15 éléments :

– tri des éléments 0, 4, 8, 12

– puis des éléments 1, 5, 9, 13

– puis des éléments 2, 6, 10, 14

– et enfin 3, 7, 11

• Chaque tri est indépendant du précédent

1, 5, 9, 13 – puis des éléments 2, 6, 10, 14 – et enfin 3,

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

static void insertion1 (double[] a, int l, int r) { for (int i = l+1; i <= r; i++)

for (int j = i; j > l; j--) compExch(a, j-1, j);

TriTri parpar insertioninsertion (4)(4)

}

static void insertion(ITEM[] a, int l, int r) { int i; for (i = r; i > l; i--) compExch(a, i-1, i); for (i = l+2; i <= r; i++){ int j = i; ITEM v = a[i]; while (less(v, a[j-1])) { a[j] = a[j-1]; j--;

}

a[j] = v;

1.Sortir plus tôt de la boucle interne

2.Une sentinelle

3.Les échanges :

t=a[j]; a[j]=a[j-1]; a[j-1]=t; suivi de t=a[j-1]; a[j-1]=a[j-2]; a[j-2]=t;

}

}

2.Une sentinelle 3.Les échanges : t=a[j]; a[j]=a[j-1]; a[j-1]=t; suivi de t=a[j-1]; a[j-1]=a[j-2]; a[j-2]=t; } }

LLalgotithmealgotithme ShellSortShellSort

static void shell(ITEM[] a, int l, int r) { int h; for (h = 1; h <= (r-l)/3; h = 3*h+1); for ( ; h > 0; h /= 3) for (int i = l+h; i <= r; i++) { int j = i; ITEM v = a[i];

r-l

r-l/3

h

15

5

4

25

8

4, 13

30

10

4, 13

100

33

4, 13, 40

}

}

while (j >= l+h && less(v, a[j-h])) { 500 163 4, 13, 40, 121 a[j] = a[j-h]; j -= h;

}

a[j] = v;

La série complète :

• de Knuth : 1, 4, 1 3, 40, 121, 364, 1093, 3280,

9841,

• qualité des incréments : premiers entre eux

• Recherche de la meilleure séquence !!

0 14 15

Exemple Exemple de de « « shell shell sort sort » » 13-tri 4-tri 1-tri

ExempleExemple dede «« shellshell sortsort »»

13-tri 4-tri 1-tri
13-tri
4-tri
1-tri

• Un 13-tri est d’abord effectué

• Puis un 4-tri

• Enfin un 1-tri

– les éléments ne sont plus échangés sur une longue distance

• pour le 1-tri, un élément est propagé au plus de 4 positions

A la fin, le tableau est trié

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

ComportementComportement desdes sséériesries

• gauche : 121, 40, 13, 4, 1

• droite : 209, 109, 41, 19, 5, 1

A

A

• première série est plus efficace

la

ries ries • gauche : 121, 40, 13, 4, 1 • droite : 209, 109, 41,

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

ChoixChoix desdes coefficientscoefficients

• Exemple de séries :

– 3*i+1 (Knuth) : 1, 4, 13, 40, 121, 364, 1093, 3280, 9841,

– 4 i+1 +3*2 i +1, i>0 : 1, 8, 23, 77, 281, 1073, 4193, 16577,

– séquence originale proposée par Shell en 1959 :

16577, – séquence originale proposée par Shell en 1959 : • 1, 2, 4, 8, 16,

• 1, 2, 4, 8, 16, 32, 64, 128, 256,

• mauvais comportement

– série de Pratt (1971)

• Efficacité de ShellSort dépend de la suite, par exemple

– la série de Knuth est bornée par les fonction N(logN) 2 et N 1.25

– série 4 i+1 +3*2 i +1 : N 3/4

– série de Pratt: N*(logN) 2

TrierTrier unun jeujeu dede donndonnééeses alalééatoireatoire avecavec ShellSortShellSort

• Rapproche les données globalement dans l’ordre à chaque étape :

– tout d’abord 40-tri

– puis 13-tri

– puis 4-tri

– et enfin 1-tri

globalement dans l’ordre à chaque étape : – tout d’abord 40-tri – puis 13-tri – puis

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

EtudeEtude empiriqueempirique desdes sséériesries

Etude empirique empirique des des s s é é ries ries • ShellSort beaucoup plus rapide
Etude empirique empirique des des s s é é ries ries • ShellSort beaucoup plus rapide

• ShellSort beaucoup plus rapide que les tris simples précédents

• Selon la séquence ShellSort est encore plus efficace d’un facteur 5:

comparer les séries O et S

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

QuickSortQuickSort

CaractCaractééristiquesristiques dynamiquesdynamiques dede ShellSortShellSort

• incrément : 209, 109, 41, 19, 5, 1

• Tri n’est pas influencé par le type de données b

a cd e
a
cd
e

– a : aléatoire

– b : gaussienne

– c : ordonnée

– d : ordre-inverse

– e ordonné-10 clés

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

OrigineOrigine dede llalgorithmealgorithme QuickSortQuickSort

• Origine : inventé par C. A. R. Hoare en 1960

• Populaire car facile à implémenter

• Avantage :

– Complexité proportionnelle à NlogN pour trier N éléments

– une boucle interne courte

• Inconvénient :

– instabilité de l’algorithme

– au pire nécessite N 2 opérations

PrincipePrincipe dede llalgorithmealgorithme QuickSortQuickSort

• Applique la stratégie diviser pour gagner

– divise les données en 2 : le point de partitionnement dépend des données

– c.a.d place un élément à la bonne place

• Les propriétés suivantes sont vérifiées à tout moment :

– a[i] est en position final pour un i donné, alors

– a[i-1] est plus grand

aucun élément a[l],

,

– a[r] est plus petit

aucun élément a[i+1],

,

que a[i]

que a[i]

est plus grand aucun élément a[l], , – a[r] est plus petit aucun élément a[i+1], ,
est plus grand aucun élément a[l], , – a[r] est plus petit aucun élément a[i+1], ,
est plus grand aucun élément a[l], , – a[r] est plus petit aucun élément a[i+1], ,

LLalgorithmealgorithme QuickSortQuickSort

static void quicksort(ITEM[] a, int l, int r) { if (r <= l) return;

int i = partition(a, l, r); quicksort(a, l, i-1); quicksort(a, i+1, r);

}

static int partition(ITEM a[], int l, int r) {

int i = l-1,

ITEM v = a[r]; for (;;) {

j = r;

while (less(a[++i], v)) ; while (less(v, a[--j])) if (j == l) break; if (i >= j) break; exch(a, i, j);

}

exch(a, i, r);

return i;

}

ExempleExemple dede partitionnementpartitionnement

• On utilise l’élément le plus à droite

• Puis on scanne de la gauche vers la droite

• Puis de la droite vers la gauche

l’élément le plus à droite • Puis on scanne de la gauche vers la droite •

LesLes performancesperformances dede QuickSortQuickSort

• Dans le pire des cas QuickSort nécessite N 2 /2 comparaisons

– cas d’un fichier déja trier : N + (N-1) +

• La situation idéale :

+ 2 + 1

– la méthode de partitionnement divise exactement le jeu de données en 2

– Résoudre la récurrence : C N = 2C N/2 + N NlgN

• La situation moyenne pour N nombres aléatoires :

– C N ?

– pour C 0 =C 1 =0; pour N 2,

• N+1 comparaisons, le +1 provient du croisement des indices

• la probabilité est de 1/N de sélectionner le k-ème élément comme point de partition

• On recommence le tri sur 2 sous-ensembles de taille k et N-k

• la formule devient :

1

N

k N

1 ≤ ≤

C

N

1

= N + +

(

C

k

1

+

C

N k

)

SimplificationSimplification dede lala rréécurrencecurrence 1 C = N + 1 + ∑ ( C +
SimplificationSimplification dede lala rréécurrencecurrence
1
C
= N +
1 +
∑ (
C
+
C
)
N
k
N − k
N
1 ≤ ≤
k
N
C
+ +
C
=
C
+ +
C
2
0
N
1
N
1
0
= + 1 +
N
∑ C
k
− 1
N
1 ≤ ≤
k
N
• Éliminer la somme en multipliant C N et C N-1 par N et N-1
respectivement puis calculer N*C N – (N-1)*C N-1
N C
*
(
N
1)*
C
=
N N
(
+
1)
(
N
1)
N
+
2
C
N
N
1
N
1
N C
*
=
(
N
+
1)*
C
+
2
N
N
N − 1

AmAmééliorationlioration dede QuickSortQuickSort

• Choix du point de partitionnement : le milieu !! :

– choix aléatoire pour évitez le pire des cas : comportement en N 2

– médiane de 3 valeurs : en position l, r et m=(l+r)/2 puis remplacer celui du milieu avec la position (r-1)

– l’ordre est le suivant : l, m puis r et on met m en position (r-1)

– gain de 5%

• Stopper l’appel récursif pour des ensembles de petites tailles

– car un algorithme récursif perd énormément de temps sur les petits jeux de données

– stopper l’appel dès que la taille est plus petite qu’une valeur donnée M pouvant variée de 5 à 25

– utiliser un algorithme plus simple : if ( (r-l) <= M) ) insertion(a, l, r); gain 10%

– plus efficace encore : if ( (r-l) <= M) ) return; et faire l’appel à la méthode de tri par insertion tout à la fin

SuiteSuite dede lala simplificationsimplification • Diviser les 2 cotés par N*(N+1) N * C =
SuiteSuite dede lala simplificationsimplification
• Diviser les 2 cotés par N*(N+1)
N * C
=
(
N
+
1)*
C
+
2
N
N
N − 1
C
C
2
• d’ou on obtient :
N
N − 1
=
+
N
+ 1
N
N + 1
C
2
2
Coût :
2N*lnN
N
− 2
=
+
+
ou 1.39*N*lgN
N
− 1
N
N + 1
à comparer à N*lgN pour le cas
idéal
=
C
2
2
=
+
3
k
+ 1
3 ≤ ≤
k N
N
C
1
1
N
≈ 2
2
dx
=
2 ln
N
=
1.39 lg
N
N
+ 1
k
x
1 ≤ ≤
k N
1
AmAmééliorationlioration dede QuickSortQuickSort
private final static int M = 10;
static void quicksort(ITEM[] a, int l, int r) {
if (r-l <= M) return;
exch(a, (l+r)/2, r-1);
compExch(a, l, r-1);
Valeur médiane de 3 valeurs
compExch(a, l, r);
compExch(a, r-1, r);
int i = partition(a, l+1, r-1);
quicksort(a, l, i-1);
quicksort(a, i+1, r);
}
static void hybridsort(ITEM a[], int l, int r) {
quicksort(a, l, r);
insertion(a, l, r);
(l+r)/2
}
l
r

PerformancePerformance dede QuickSortQuickSort

Performance Performance de de QuickSort QuickSort

AutresAutres amamééliorationsliorations

• Remplacer l’appel à des méthodes par du code « inline », le gain faible car ces méthodes ne sont pas dans les boucles internes

• Boucle interne en assembleur

• Utiliser des sentinelles,

• Médiane de 5 éléments

• Programme non récursif pour contrôler la taille de la pile

– pour des données aléatoires la taille de la pile n’est pas un problème

– mais pour des données dégénérées la pile peut avoir une taille anormalement grande

– limiter cette situation en traitant d’abord les petits jeux de données

QuickSort QuickSort avec avec diff diff é é rentes rentes donn donn é é es

QuickSortQuickSort avecavec diffdifféérentesrentes donndonnééeses

• Utilise le partitionnement à partir de la médiane de 3 points

• Le partitionnement de la médiane des 3 valeurs est robuste et réalise un tri efficace sur les jeux de données dégénérées :

– gaussiennes (2)

– presque triées

– en ordre inverse

– par palier

QuickSortQuickSort nonnon rréécursifcursif

static void quicksort(ITEM[] a, int l, int r) { intStack S = new intStack(50); S.push(l); S.push(r); while (!S.empty()) { r = S.pop(); l = S.pop(); if (r <= l) continue; int i = partition(a, l, r); if (i-l > r-i) { S.push(l); S.push(i-1); } S.push(i+1); S.push(r); if (r-i >= i-l) { S.push(l); S.push(i-1); }

}

}

TailleTaille dede lala pilepile avecavec QuickSortQuickSort • Pour des données aléatoire : la taille de
TailleTaille dede lala pilepile
avecavec QuickSortQuickSort
• Pour des données aléatoire : la
taille de la pile n’est pas trop
grande
• Mais pour des données
dégénérées ceci peut engendrer
des problèmes
• Exemples :
– 2 jeux aléatoires à gauche
– 1 jeu de données
partiellement ordonné
hauteur de la pile

ArbreArbre dede partitionnementpartitionnement dede QuickSortQuickSort

• Un nœud : le point de partitionnement

• On obtient un arbre binaire

partitionnement de de QuickSort QuickSort • Un nœud : le point de partitionnement • On obtient
partitionnement de de QuickSort QuickSort • Un nœud : le point de partitionnement • On obtient
partitionnement de de QuickSort QuickSort • Un nœud : le point de partitionnement • On obtient
partitionnement de de QuickSort QuickSort • Un nœud : le point de partitionnement • On obtient

TrierTrier lesles petitspetits jeuxjeux dede donndonnééeses enen premierpremier

Ordre des traitements :

Programme récursif

Programme non-récursif petits lots traités en premier

premier • Ordre des traitements : Programme récursif Programme non-récursif petits lots traités en premier
premier • Ordre des traitements : Programme récursif Programme non-récursif petits lots traités en premier
QuickSort QuickSort • Tri de 200 éléments • Visualisation des partitionnements successifs • Un seuil

QuickSortQuickSort

• Tri de 200 éléments

• Visualisation des partitionnements successifs

• Un seuil M = 15

AlgorithmesAlgorithmes dede tritri avecavec desdes listeslistes chachaîînnééeses

Les algorithmes précédents peuvent aussi être implémentés pour des listes

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

TriTri parpar sséélectionlection

private static Node findMax(Node h) { for (Node t = h; t.next != null; t = t.next) if (h.next.item < t.next.item) h = t; return h;

}

static Node sort(Node h) { Node head = new Node(-1, h), out = null; while (head.next != null) {

Node max = findMax(head); Node t = max.next; max.next = t.next; t.next = out; out = t;

}

return out;

}

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

TriTri dduneune listeliste chachaîînnééee

• Gestion de 2 listes : entrée référencée par h.next, et sortie référencée par out

référencée par h.next, et sortie référencée par out – entrée : mémorise 2 références, max et

– entrée : mémorise 2 références, max et t,

– h le début de la liste

• la sortie représente la liste triée à la fin

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

IlIl existeexiste dede nombreuxnombreux algorithmesalgorithmes dede tritri spspéécialiscialisééss

clés dupliquées

tri par fusion (top-down, bottom-up)

algorithme particulier pour des clés entières

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

LLalgorithmealgorithme «« HeapHeap SortSort »»

Mais auparavant une introduction aux arbres

Copyright " 'Algorithms in Java'; Robert Sedgewick & Michael Shildlowsky; Third edition, Parts 1-4; Addison-Wesley " Reproduction ULP Strasbourg. Autorisation CFC - Paris

CaractCaractééristiquesristiques dynamiquesdynamiques dede QuickSortQuickSort

Caract Caract é é ristiques ristiques dynamiques dynamiques de de QuickSort QuickSort
Autorisation CFC - Paris Caract Caract é é ristiques ristiques dynamiques dynamiques de de QuickSort QuickSort