Télécharger la présentation
La présentation est en train de télécharger. S'il vous plaît, attendez
Publié parGauthier Simoneau Modifié depuis plus de 9 années
1
Structures de données IFT-2000 Abder Alikacem Semaine 14 Les algorithmes de tri Département d’informatique et de génie logiciel Édition septembre 2009
2
Plan Définitions et propriétés Les algorithmes de tri simples et leur complexité Les algorithmes de tri complexes et leur complexité Le tri rapide (QuickSort) Le tri-fusion (MergeSort) Le tri par monceau (HeapSort)
3
Traitement de données triées Le traitement de données déjà triées est plus rapide. Nécessaire pour le traitement séquentiel d’intervalles. Il faut trier des données à bas coût ! nb de comparaisons nb de déplacements d’éléments espace mémoire requis Besoin : attribut de tri (clé) :, que l’on peut comparer { } (c.-à-d. ordre total) déplacer toute l’information : ou, + indirection vers l’information
4
Critères d'analyse Complexité en temps : 2 critères de base nombre de comparaisons entre clés nombre de transferts (ou d’échanges) d'éléments Complexité en place mémoire : nécessaire au tri tri sur place (in situ) : en O(1) tri à côté : en O(n) tri récursif : utilise une pile Stabilité conserve l'ordre originel pour éléments de clés égales Progressivité à l'étape k trie les k premiers éléments de la liste Configuration particulière des données : aléatoires, triées, inversées, égales, presque triées
5
Les algorithme de tri Les algorithmes de tri «classiques»: Tris élémentaires tri insertion; tri sélection; Etc.. Tris dichotomiques tri rapide (Quick Sort); tri fusion; Tris par structure tri par arbre (Tree Sort); tri par monceau (Heap Sort) tri pigeonnier (Pigeon Hole). tri basique Tri aléatoire … et le Bogo tri
6
Méthodes simples de tri Intérêts pédagogiques (terminologie et mécanismes fondamentaux) Tris simples plus efficaces sur des petites listes (moins de 50 éléments) sur des listes presque triées sur des listes contenant un grand nombre de clés égales Certains tris complexes sont améliorés en faisant appel à des tris simples sur une partie des données
7
Tris simples Algorithme#1 : Tri par insertion (trace en classe) insérer chacun des n éléments à la bonne place dans le tableau créé jusqu’ici 44,55,12,42,94,18,06,67
8
Tris simples Tri par insertion template void TriInsertion( T Tableau[], int n) { int j; T Tmp; for (int i=1; i<n; i++ ) { //Placer l'element courant dans la variable tampon Tmp = Tableau[i]; j=i; //Tant que la position d'insertion n'est pas atteinte... while ( (--j>=0) && (Tmp<Tableau[j]) ) Tableau[j+1]=Tableau[j]; Tableau[j+1]=Tmp; }
9
Tris simples Tri par insertion dichotomique : Idée au lieu de parcourir les i premiers éléments triés pour faire l'insertion du i + 1 ième, rechercher la place où insère par dichotomie. Complexité nb de transferts est identique à celui de l'insertion séquentielle O(n 2 ) dans le pire des cas et en moyenne nb de comparaisons en O(n log n) (au pire et en moyenne) En pratique : n'améliore pas vraiment les performances
10
Tris simples Tri par insertion : insérer chacun des n éléments à la bonne place dans le tableau créé jusqu’ici … tri stable? tri in situ? progressif? Meilleur cas : séquence triée nb de comparaisons ? O(n) O(n log n) nb de déplacements ? O(1) Pire cas : séquence triée inverse nb de comparaisons ? O(n 2 ) O(n log n) nb de déplacements ? O(n 2 )
11
Tri shell, Donald Shell Une variante du tri par insertion Lenteur du tri par insertion les échanges ne portent que sur des voisins si le plus petit élément est à la fin il faut n étapes pour le placer définitivement Principe du tri shell éliminer les plus grands désordres pour abréger le travail aux étapes suivantes Idée ordonner des séries d'éléments éloignés de h, h prenant de valeurs de plus en plus petites (jusqu'à 1) Exemple (suite déterminée empiriquement) h n = (1093, 384, 121, 40, 13, 4, 1) H n+1 = 3 h n +1 Tris simples
12
Tri shell template void triShell(T Tableau[], int n) { … while (p <= n) { p = (3 * p) + 1; } while (p > 0) { …. p = p/3; }
13
Tri shell On a démontré que la complexité dans le pire des cas est O(n 3/2 ). En choisissant pour suite d'incréments 1, 3, 7, 15, 31 ( h i+1 = 2h i + 1) on obtient expérimentalement une complexité en O(n 1,2 ). Très efficace jusqu'à 5000 éléments que les données soient aléatoires, triées ou en ordre inverse, code facile et compact, conseillé quand on n'a aucune raison d'en choisir un autre. Tris simples tri stable? tri in situ? progressif?
14
3 1 5 4 6 4 7 8 1 7 4 2 3 1 5 4 6 4 1 8 7 7 4 2 1 2323 4 5 6 7 8 9 10 11 12 1 2323 4 5 6 7 8 9 10 11 12 reste à classer MIN échange Tris simples Recherche du minimum par balayage séquentiel Algorithme#2 : Tri par sélection remplir les cases de 1 à n avec le minimum des éléments du tableau restant
15
Tris simples Tri par sélection (trace en classe): 44,55,12,42,94,18,06,67 Algorithme : remplir les cases de 1 à n avec le minimum des éléments du tableau restant
16
Tri par sélection template template void TriSelection(T Tableau[], int n) { int min; int min; T Tmp; T Tmp; for (int i=0 ; i<n-1 ; i++ ) { for (int i=0 ; i<n-1 ; i++ ) { //Recherche de l'indice du plus petit element //Recherche de l'indice du plus petit element min = i; min = i; for (int j=i+1 ; j<n ; j++ ) { for (int j=i+1 ; j<n ; j++ ) { if ( Tableau[j]<Tableau[min] ) if ( Tableau[j]<Tableau[min] ) min = j; min = j; } //Permutation des elements //Permutation des elements Tmp = Tableau[i]; Tmp = Tableau[i]; Tableau[i] = Tableau[min]; Tableau[i] = Tableau[min]; Tableau[min] = Tmp; Tableau[min] = Tmp; }} Tris simples
17
Tri par sélection remplir les cases de 1 à n avec le minimum des éléments du tableau restant Meilleur cas : séquence triée nb de comparaisons ? O(n 2 ) nb de déplacements ? O(1) Pire cas : séquence triée inverse nb de comparaisons ? O(n 2 ) nb de déplacements ? O(n) tri in situ ? progressif ? stable ? Stable? 21,17,21,5,2,9,2,7
18
Tris simples 1 4 2 3 5 5 4 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 Les balayages peuvent être éliminés Algorithme#3 : Tri à bulles (« Bubblesort ») remonter les plus petites valeurs à la surface, et ce, à chaque itération
19
Tris simples Tri à bulles (« Bubblesort ») : trace en classe 44,55,12,42,94,18,06,67 Algorithme : remonter les plus petites bulles à la surface, et ce, à chaque itération
20
Tri à bulles (« Bubblesort ») template template void TriBulle( T Tableau[], int n) { T Tmp; for (int i=0; i<n-1; i++) for (int j=n-1; j>i; j--) if ( Tableau[j-1]> Tableau[j]) { Tmp = Tableau[j-1]; Tableau[j-1] = Tableau[j]; Tableau[j] = Tmp; }} Tris simples
21
Tri à bulles (« Bubblesort ») remonter les plus petites bulles à la surface, et ce, à chaque itération Meilleur cas : séquence triée nb de comparaisons ? O(n 2 ) nb de déplacements ? O(1) Pire cas : séquence triée inverse nb de comparaisons ? O(n 2 ) nb de déplacements ? O(n 2 ) tri stable? tri in situ? progressif?
22
Tris simples Tri à bulles (« Bubblesort ») Première amélioration Une première amélioration consiste à arrêter le processus s'il n'y a aucun échange dans une passe. Deuxième amélioration : ShakerSort Une deuxième amélioration consiste à alterner le sens des passes. Troisième amélioration Une troisième qui consiste à reprendre au début chaque fois qu’il y a une permutation.
23
Complexité en temps : en O(n 2 ) en moyenne et au pire des cas en nombre de transferts ou en nombre de comparaisons en O(n²). en espace : en O(1) (tris sur place) Sauf tri shell ne conviennent pas pour un nombre important de données Faciles à comprendre et à mettre en œuvre Tris simples
24
Tri rapide (« Quicksort ») Tri dichotomique appelé aussi tri des bijoutiers Idée : trier les perles avec des tamis plus ou moins fins pour chaque tamis on sépare les perles en deux sous-ensembles (celles qui passent et celles qui restent dans le tamis) puis on trie celles qui sont passées avec un tamis plus fin et les autres avec un tamis plus gros Tris complexes
25
Tri rapide (« Quicksort ») Partage avec pivot = 3 32417236 32217436 32213476 31223467 TRI < 3 3 Suite du tri Algorithme choisir un pivot p (élément médian) partager le tableau en 2 : sous-tableau de gauche : éléments ≤ p sous-tableau de droite : éléments > p l’élément entre les 2 le pivot est à sa place définitive appel récursif avec le sous-tableau de gauche appel récursif avec le sous-tableau de droite Trace en classe: 44,55,12,42,94,18,06,67
26
Tris complexes 06,12,18,42,44,55,67,94 Meilleur cas : pivot = médiane nb de comparaisons ? O(n log n) nb de déplacements ? O(1) Pire cas : nb de comparaisons ? nb de déplacements ? n/4 tri rapide (« Quicksort ») : 06,12,18,42,44,55,67,94 n/2
27
Tris complexes n-4 n-3 06,12,18,42,44,55,67,94 n-2 n-1 tri rapide (« Quicksort ») : 06,12,18,42,44,55,67,94 Meilleur cas : pivot = médiane nb de comparaisons ? O(n log n) nb de déplacements ? O(1) Pire cas : pivot = min. ou max. nb de comparaisons ? O(n 2 ) nb de déplacements ? O(n 2 )
28
Problèmes du « Quicksort » Algorithme récursif taille de la pile = ? meilleur cas :O(log n) pire cas :O(n) en moyenne : O(log n) Comment faire pour minimiser la taille de la pile ? empiler toujours de sous-tableaux de taille optimum Tout dépend du choix du pivot du pire cas : O(n 2 ) au meilleur cas : O(n log n) Comment choisir un bon pivot ?
29
la solution idéale est de trouver à chaque fois la valeur médiane du sous-tableau à trier, mais sa recherche précise rend le tri plus lent que sans elle. Une solution quelquefois utilisée est de prendre par exemple trois valeurs, pour en prendre la valeur médiane, par exemple tab[droite], tab[gauche] et tab[(droite+gauche)/2] (dans le cas d'un tableau parfaitement mélangé, le choix de trois positions n'a pas d'importance, mais dans des tableaux presque triés le choix ci- dessus est plus judicieux). La totalité de ces améliorations peut apporter un gain de l'ordre de 20% par rapport à la version de base. Problèmes du « Quicksort » Choix du pivot : du pire cas : O(n 2 ) au meilleur cas : O(n log n) Comment choisir un bon pivot ?
30
Tris complexes Tri rapide (« Quicksort ») Meilleur cas : pivot = médiane nb de comparaisons ? O(n log n) nb de déplacements ? O(1) En moyenne nb de comparaisons ? O(n log n) nb de déplacements ? O(n log n) Pire cas : pivot = min. ou max. nb de comparaisons ? O(n 2 ) nb de déplacements ? O(n 2 ) tri stable? tri in situ? progressif? Très bien compris, étudié tant au niveau théorique qu’expérimental. Très bonnes performances s'il est optimisé dérécursivé tri par insertion sur les petites listes
31
Tris complexes Tri rapide (« Quicksort ») template template void quickSort(T tableau[], int inf, int sup) { int milieu; if (sup>inf) // s'il y a au moins 2 éléments { milieu = partition(tableau, inf, sup); // trier la partie de gauche quickSort(tableau, inf, milieu); // trier la partie de droite quickSort(tableau, milieu+1, sup); }}
32
Tris complexes Tri rapide (« Quicksort ») template template int partition(T tableau[], int inf, int sup) { T pivot, tempo; int i,j; pivot = tableau[(sup+inf)/2]; i = inf-1; j = sup+1; // Suite a la page suivante
33
Tris complexes Tri rapide (« Quicksort ») while ( i<j ) // tant que les index ne croisent pas { // conserver les éléments plus petits ou égaux { // conserver les éléments plus petits ou égaux //au pivot à sa gauche //au pivot à sa gauche do do { i++; { i++; } while (tableau[i]<pivot); } while (tableau[i]<pivot); // conserver les éléments plus grands ou // conserver les éléments plus grands ou //égaux au pivot à sa droite //égaux au pivot à sa droite do do { j--; { j--; } while (tableau[j]>pivot); } while (tableau[j]>pivot); // Permuter les éléments qui ne sont pas // Permuter les éléments qui ne sont pas // à leur place // à leur place if ( i<j) if ( i<j) {tempo = tableau[i]; {tempo = tableau[i]; tableau[i]= tableau[j]; tableau[j]= tempo; } } return j; } return j; }
34
Tri par fusion Diviser Diviser la séquence de n éléments à trier en 2 sous-séquences de taille n/2 Régner Trier les 2 sous-séquences Combiner Fusionner les 2 sous-séquences triées Tris complexes
35
Tri par fusion
36
1n1m Trié 1 n+m Trié t1 t3 t2 template template void triFusion(T t[], int debut, int fin) { if(debut<fin) { int milieu=(debut+fin)/2; triFusion(t, debut, milieu); triFusion(t, milieu+1, fin); fusionner(t, debut, milieu, fin); }}
37
void fusionner(T t[], int debut, int milieu, int fin) { int i1=debut; // indice courant dans t[debut..milieu] int i2=milieu+1; // indice courant dans t[milieu+1..fin] int i3=0; // indice courant dans t3 (tableau auxiliaire) T *t3; // tableau auxiliaire dynamique de longueur fin-debut+1 t3= new T[fin-debut+1]; while((i1<=milieu)&&(i2<=fin)) { if(t[i1]<t[i2]) { t3[i3]=t[i1]; i1++;} else { t3[i3]=t[i2]; i2++; } i3++; } if(i1>milieu) // on a epuisé t[debut..milieu] for(;i2<=fin;i2++,i3++) t3[i3]=t[i2]; else // on a epuisé t[milieu+1..fin] for(;i1<=milieu;i1++,i3++) t3[i3]=t[i1]; // il faut transférer t3 à sa place dans t for(i1=0;i1<i3;i1++){ t[i1+debut]=t3[i1]; } delete [] t3; }
38
Tri par fusion Comparaison avec le tri QuickSort Tris complexes Stabilité? in situ? Progressivité? Complexité?
39
Tri par arbre (« Heapsort ») : trace en classe 44,55,12,42,94,18,06,67 Algorithme bâtir une structure d’arbre sur place h i h 2i h i h 2i+1 structure appelée « monceau » (« heap ») Tris complexes
40
Monceau - définition Tris complexes Un arbre complet tel que pour chaque noeud N dont le parent est P, la clé de P est plus grande que celle de N Normalement implémenté dans un tableau Insertion et retrait sont O(log n) dans le pire cas Insertion est O(1) en moyenne Recherche du plus petit élément est O(1) dans le pire cas
41
Tris complexes Tri par arbre (« Heapsort ») 44 55 9442 67 12 18 06 5512429418066744 23456781
42
Tris complexes Création du monceau 44 55 9442 67 12 18 06 5512429418066744 23456781
43
Tris complexes 44 55 9442 67 12 18 06 5512429418066744 23456781
44
Tris complexes 44 55 9467 42 12 18 06 5512679418064244 23456781
45
Tris complexes 44 55 9467 42 12 18 06 5512679418064244 23456781
46
Tris complexes 44 55 9467 42 12 18 06 5512679418064244 23456781
47
Tris complexes 44 55 9467 42 18 12 06 5518679412064244 23456781
48
Tris complexes 44 55 9467 42 18 12 06 5518679412064244 23456781
49
Tris complexes 44 94 5567 42 18 12 06 9418675512064244 23456781
50
Tris complexes 44 94 5567 42 18 12 06 9418675512064244 23456781
51
Tris complexes 94 44 5567 42 18 12 06 4418675512064294 23456781
52
Tris complexes 94 67 5544 42 18 12 06 6718445512064294 23456781
53
Tris complexes 94 67 5544 42 18 12 06 6718445512064294 23456781
54
Tris complexes Monceaux dans la STL Fonction pour créer un monceau: make_heap(Iterator deb, Iterator fin) Fonctions pour insérer et retirer un élément push_heap(Iterator deb, Iterator fin) pop_heap(Iterator deb, Iterator fin) Toutes ces fonctions ont une seconde version avec un troisième argument qui est un prédicat qui permet de redéfinir l’opérateur de comparaison utilisé Note: l’itérateur doit être un itérateur à accès direct, ce qui limite les possibilités de conteneurs (vector et deque)
55
Tris complexes Monceaux dans la STL Il existe aussi un adaptateur priority_queue On peut choisir le type de conteneur et de fonction de comparaison Offre les fonctions suivantes: –push() –top() –pop() Voir les exemples fournis en exemple dans la semaine 14
56
Tris complexes Le tri 94 67 5544 42 18 12 06 6718445512064294 23456781
57
Tris complexes 42 67 5544 94 18 12 06 6718445512069442 23456781
58
Tris complexes 42 67 5544 94 18 12 06 6718445512069442 23456781
59
Tris complexes 42 67 5544 94 18 12 06 6718445512069442 23456781
60
Tris complexes 67 42 5544 94 18 12 06 4218445512069467 23456781
61
Tris complexes 67 55 4244 94 18 12 06 5518444212069467 23456781
62
Tris complexes 67 55 4244 94 18 12 06 5518444212069467 23456781
63
Tris complexes 06 55 4244 94 18 12 67 5518444212679406 23456781
64
Tris complexes 55 06 4244 94 18 12 67 0618444212679455 23456781
65
Tris complexes 55 44 4206 94 18 12 67 4418064212679455 23456781
66
Tris complexes 55 44 4206 94 18 12 67 4418064212679455 23456781
67
Tris complexes 12 44 4206 94 18 55 67 4418064255679412 23456781
68
Tris complexes 44 12 4206 94 18 55 67 1218064255679444 23456781
69
Tris complexes 44 42 1206 94 18 55 67 4218061255679444 23456781
70
Tris complexes 44 42 1206 94 18 55 67 4218061255679444 23456781
71
Tris complexes 12 42 4406 94 18 55 67 4218064455679412 23456781
72
Tris complexes 42 12 4406 94 18 55 67 1218064455679442 23456781
73
Tris complexes 42 12 4406 94 18 55 67 1218064455679442 23456781
74
Tris complexes 06 12 4442 94 18 55 67 1218424455679406 23456781
75
Tris complexes 18 12 4442 94 06 55 67 1206424455679418 23456781
76
Tris complexes 18 12 4442 94 06 55 67 1206424455679418 23456781
77
Tris complexes 06 12 4442 94 18 55 67 1218424455679406 23456781
78
Tris complexes 12 06 4442 94 18 55 67 0618424455679412 23456781
79
Tris complexes 12 06 4442 94 18 55 67 0618424455679412 23456781
80
Tris complexes 06 12 4442 94 18 55 67 1218424455679406 23456781
81
Tris complexes 06 12 4442 94 18 55 67 1218424455679406 23456781
82
Tris complexes « Heapsort » Algorithme créer le monceau en descendant les clés trier en échangeant le maximum et le dernier + redescendre complexité ? O(n log n) en tout temps! aucun espace additionnel requis !!! Stabilité ? in situ ? Progressivité ?
83
Autres tris Si le tableau contient un grand nombre de valeurs similaires: algorithme par comptage ou tri par pigeonnier. Dans la cas où les clefs sont bornées (c'est à dire comprises entre un minimum et un maximum connus à l'avance) et en nombre fini: algorithme de tri basique (tri par bacs). ..et bien sûr le bogo tri! Conclusion
84
Ils sont présents dans la bibliothèque sort(): Doit garantir un temps moyen dans O(n lg n) Le tri rapide (quicksort) répond à ce critère stable_sort(): Doit garantir O(n lg n) dans le pire cas Peut utiliser de la mémoire supplémentaire Le tri par fusion (mergesort) répond à ce critère partial_sort() Doit garantir un temps moyen dans O(n lg n) Doit permettre le tri partiel Le tri par monceau (heapsort) répond à ce critère Les tris dans la STL
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.