Les tris 1 Les tris Traitement de donnes
- Slides: 42
Les tris 1
Les tris 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 2
Les tris Tri selon une relation d’ordre § Besoin : § attribut de tri : <nom, …>, <nom, prenom, . . . > § generalement une cle § que l’on peut comparer {<, ==, >} § deplacer toute l’information : <cle, . . . > § ou <cle, indirection>, + indirection vers l’information 3
Les tris Tris simples § tri par insertion : 44, 55, 12, 42, 94, 18, 06, 67 § Algorithme : § insérer chacun des n elements à la bonne place dans le tableau creéé jusqu’ici 4
Les tris Tris simples § tri par insertion : 44, 55, 12, 42, 94, 18, 06, 67 44 44, 55 12, 42, 44, 55 12, 44, 55, 94 12, 18, 42, 44, 55, 94 06, 12, 18, 42, 44, 55, 67, 94 5
Les tris Tris simples § tri par insertion : #include <stdio. h> #define CN 0 #define OK 1 typedef int Type. El; void tri. Insertion(Type. El tab[], int n, int * err); void main() { Type. El x[]={44, 55, 12, 42, 94, 18, 6, 67}; int nbr, i; nbr=sizeof(x)/sizeof(Type. El); printf("Le tableau non trien"); for(i=0; i<nbr; i++) printf("%3 d", x[i]); printf("n"); int err; tri. Insertion(x, nbr, &err); printf("Le tableau trien"); for(i=0; i<nbr; i++) printf("%3 d", x[i]); } 1/2 6
Les tris Tris simples § tri par insertion : void tri. Insertion(Type. El tab[], int n, int * err) 2/2 { /* connu: - entree: tab, n sortie: ----resultat: tab trie et *err = OK, si n >= 0, tab est inchange et *err = CN, sinon. hypothese: n >= 0 */ int i, j; Type. El x; if(n < 0) { *err = CN; return; } *err = OK; for(i = 1; i < n; i++) { j = i; x = tab[i]; while(j-1 >= 0 && x < tab[j-1]) { tab[j] = tab[j-1]; j--; } tab[j] = x; 7 } }
Les tris Tris simples § tri par insertion : Le tableau non trie 44 55 12 42 94 18 6 67 Le tableau trie 6 12 18 42 44 55 67 94 8
Les tris Tris simples § tri par insertion : § Meilleur cas : séquence triée § nb de comparaisons ? O(n) § nb de deplacements ? O(n) § Pire cas : séquence triée inverse § nb de comparaisons ? O(n 2) § nb de deplacements ? O(n 2) 9
Les tris Tris simples § tri par sélection : 44, 55, 12, 42, 94, 18, 06, 67 § Algorithme : § remplir les cases de 1 à n avec le minimum des éléments du tableau restant 10
Les tris Tris simples § tri par sélection : 44, 55, 12, 42, 94, 18, 06, 67 06, 55, 12, 42, 94, 18, 44, 67 06, 12, 55, 42, 94, 18, 44, 67 06, 12, 18, 42, 94, 55, 44, 67 06, 12, 18, 42, 44, 55, 94, 67 06, 12, 18, 42, 44, 55, 67, 94 11
Les tris Tris simples § tri par sélection : #include <stdio. h> #define CN 0 #define OK 1 typedef int Type. El; void tri. Selection(Type. El tab[], int n, int * err); void main() { Type. El x[]={44, 55, 12, 42, 94, 18, 6, 67}; int nbr, i; nbr=sizeof(x)/sizeof(Type. El); printf("Le tableau non trien"); for(i=0; i<nbr; i++) printf("%3 d", x[i]); printf("n"); int err; tri. Selection(x, nbr, &err); printf("Le tableau trien"); for(i=0; i<nbr; i++) printf("%3 d", x[i]); } 1/3 12
Les tris Tris simples § tri par sélection : void tri. Selection(Type. El tab[], int n, int * err) 2/3 { /* connu: - entrée: tab, n; sortie: - résultat: tab trié et *err = OK, si n>= 0 tab est inchangé et *err = CN, sinon. hypothese: n >= 0 */ int i, j, pos; Type. El x; for(i = 0; i < n -1; i++) { pos = i; x = tab[i]; for(j = i + 1; j < n; j++) { if (tab[j] < x) { x = tab[j]; pos = j; } } 13
Les tris Tris simples § tri par sélection : /*x est l’élément minimum du sous-tableau non trié*/ if (x != tab[i]) { tab[pos] = tab[i]; tab[i] = x; } } //fin de boucle for } //fin de la fonction 3/3 Le tableau non trie 44 55 12 42 94 18 6 67 Le tableau trie 6 12 18 42 44 55 67 94 14
Les tris Tris simples § tri à bulles (Bubblesort) : 44, 55, 12, 42, 94, 18, 06, 67 § Algorithme : § remonter les plus petites bulles à la surface, et ce, à chaque itération 15
Les tris Tris simples § tri à bulles (Bubblesort) : 44, 55, 12, 42, 94, 18, 06, 67 06, 44, 55, 12, 42, 94, 18, 67 06, 44, 55, 12, 18, 42, 94, 67 06, 12, 44, 55, 18, 42, 67, 94 06, 12, 18, 44, 55, 42, 67, 94 06, 12, 18, 42, 44, 55, 67, 94 16
Les tris Tris simples § tri à bulles (Bubblesort) : #include <stdio. h> #define CN 0 #define OK 1 typedef int Type. El; void tri. Bulles(Type. El tab[], int n, int * err); void main() { Type. El x[]={44, 55, 12, 42, 94, 18, 6, 67}; int nbr, i; nbr=sizeof(x)/sizeof(Type. El); printf("Le tableau non trien"); for(i=0; i<nbr; i++) printf("%3 d", x[i]); printf("n"); int err; tri. Bulles(x, nbr, &err); printf("Le tableau trien"); for(i=0; i<nbr; i++) printf("%3 d", x[i]); } 1/2 17
Les tris Tris simples § tri à bulles (Bubblesort) : void tri. Bulles(Type. El tab[], int n, int * err) 2/2 { /* connu: - entrée: tab, n; sortie: - résultat: tab trié et *err = OK, si n>= 0 tab est inchangé et *err = CN, sinon. hypothese: n >= 0 int i, j, pos; Type. El x; for(i = 1; i < n; i++) { for(j = n - 1; j >= i; j--) { if ( tab[j-1] > tab[j]) { x = tab[j-1]; tab[j-1] = tab[j]; tab[j] = x; Le tableau non trie } 44 55 12 42 94 18 6 67 } Le tableau trie } 6 12 18 42 44 55 67 94 } 18
Les tris Tris simples § tri à bulles (Bubblesort) - amélioration void tri. Bulles(Type. El tab[], int n, int * err) { int i, pos, change; Type. El x; pos=1; //le nombre d’éléments triés après la boucle for do { change=0; for(i = 0; i < n-pos; i++) if ( tab[i] > tab[i+1]) { x = tab[i]; tab[i] = tab[i+1]; tab[i+1] = x; change=1; Amélioration consiste à arrêter le } processus s'il n'y a aucun échange pos++; dans une passe }while(change); 19 }
Les tris Tris simples § tri par fusion (merge sorting): § § Algorithme Fusion de deux tableaux triés en un seul plus grand, appelé récursivement sur les deux moitiés du tableau, jusqu'à une taille de tableau de 1 (ou plus, avec un tri spécifique pour petits tableaux, par exemple par échange sur des sous-tableaux de 3 éléments). 20
Les tris § tri par fusion (merge sorting): Le premier étape Le deuxième étape 21
Les tris Tris simples § tri par fusion (merge sorting): #include <stdio. h> 1/4 void merge_sort(int in[], int a, int b, int out[]); void aff_tab(int in[], int k); void merge_array(int in 1[], int in 2[], int n 1, int n 2, int out[]); int compar=0; main() { int in_tab[] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 4}; int n=sizeof(in_tab)/sizeof(int); int out_tab[20]; Le tableau non trie printf("Le tableau non trien"); 31415 aff_tab(in_tab, n); 92654 merge_sort(in_tab, 0, n-1, out_tab); printf("Le tableau trien"); Le tableau trie aff_tab(out_tab, n); 1 1 2 3 4 est %dn", compar); printf("Le nombre de comparaison 45569 } Le nombre de comparaison est 22 22
Les tris Tris simples § tri par fusion (merge sorting): Définition de la fonction d’affichage (5 éléments sur une ligne) void aff_tab(int in[], int k) { int i; for(i=1; i<=k; i++) printf("%d%c", in[i-1], i%5==0? 'n': ' '); printf("n"); } 2/4 23
Les tris Tris simples § tri par fusion (merge sorting): void merge_sort(int in[], int a, int b, int out[]) 3/4 { int m, out 1[20], out 2[20]; Définition de la fonction merge_sort if(a==b) out[0]=in[a]; else if( (b-a)==1 ) { if ( in[a]<=in[b] ) { out[0]=in[a]; out[1]=in[b]; } groupe de deux else { out[0]=in[b]; out[1]=in[a]; } compar++; } else { m=a+(b-a)/2; merge_sort(in, a, m, out 1); merge_sort(in, m+1, b, out 2); merge_array(out 1, out 2, 1+m-a, b-m, out); } 24 }
Les tris Tris simples § tri par fusion (merge sorting): void merge_array(int in 1[], int in 2[], int n 1, int n 2, int out[]) 4/4 { int i=0, j=0, k=0; while ( (i<n 1) && (j<n 2) ) { if(in 1[i] <= in 2[j]) { out[k]=in 1[i]; i++; } else { out[k]=in 2[j]; j++; } k++; Si on a des éléments dans les compar++; } deux sous-tableaux if(i !=n 1) do { out[k]=in 1[i]; i++; Définition de la fonction merge_array k++; } while(i<n 1); else Si on n’a pas d’éléments dans un do { out[k]=in 2[j]; des deux sous-tableaux j++; k++; } while(j<n 2); 25 }
Les tris Tris simples § § § tri panier (bucket sort) La grandeur de l’ensemble de base est petite, une constante fixe m On utilise m compteurs 26
Les tris Tris complexes § tri rapide (Quicksort) : § Ce tri est récursif. § On cherche à trier une partie du tableau délimitée par les indices gauche et droite. § On choisit une valeur de ce sous-tableau (une valeur médiane serait idéale, mais sa recherche ralentit plus le tri que de prendre aléatoirement une valeur, par exemple la dernière), = pivot. 27
Les tris Tris complexes § tri rapide (Quicksort) : § On cherche la position définitive de ce pivot, § On effectue des déplacements de valeurs de telle sorte que tous les éléments avant le pivot soient plus petits que lui, et que toutes celles après lui soient supérieures, mais sans cher à les classer pour accélérer le processus. § On rappelle récursivement le tri de la partie avant le pivot, et de celle après le pivot. § On arrête la récursivité sur les parties à un seul élément, nécessairement triée. § L'algorithme est achevé quand les piles ne contiennent plus aucune partie de liste à être traitée par l'étape de 28 réduction.
Les tris Tris complexes § tri rapide (Quicksort) : 44, 55, 12, 42, 94, 18, 06, 67 § 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 § appel récursif avec le sous - tableau de gauche § appel récursif avec le sous - tableau de droite 29
Les tris Tris complexes § tri rapide (Quicksort) : 44, 55, 12, 42, 94, 18, 06, 67 06, 55, 12, 42, 94, 18, 44, 67 06, 18, 12, 42, 94, 55, 44, 67 30
Les tris Tris complexes § tri rapide (Quicksort) : 06, 18, 12, 42, 94, 55, 44, 67 06, 12, 18, 42, 44, 55, 94, 67 06, 12, 18, 42, 44, 55, 67, 94 31
Les tris Tris complexes § tri rapide (Quicksort) : #include <stdio. h> typedef int Type. El; void swap(Type. El *a, int l, int r); quicksort( Type. El *a, int low, int high ); void partition( Type. El *a, int low, int high, int *pivot ); void main() { Type. El x[ ]={44, 55, 12, 42, 94, 18, 6, 67}; int nbr, i; nbr=sizeof(x)/sizeof(Type. El); printf("Le tableau non trien"); for(i=0; i<nbr; i++) printf("%3 d", x[i]); Le tableau non trie printf("n"); 44 55 12 42 94 18 6 67 quicksort(x, 0, nbr-1); Le tableau trie printf("Le tableau trien"); 6 12 18 42 44 55 67 94 for(i=0; i<nbr; i++) printf("%3 d", x[i]); } 1/4 32
Les tris Tris complexes § tri rapide (Quicksort) : Définition de la fonction quicksort( Type. El *a, int low, int high ) { int pivot; /* condition terminale! */ if ( high > low ) { partition( a, low, high, & pivot ); quicksort( a, low, pivot-1 ); quicksort( a, pivot+1, high ); } } 2/4 33
Les tris Tris complexes § tri rapide (Quicksort) : void partition( Type. El *a, int low, int high, int *pivot) 3/4 { int left, right; Type. El pivot_item; *pivot = (low+high)/2; Définition de la fonction partition pivot_item = a[*pivot]; left=low; right = high; while ( left < right ) { /* deplacer le pointeur gauche tant que element < pivot */ while( a[left] < pivot_item ) left++; /* deplacer le pointeur droite tant que element > pivot */ while( a[right] >= pivot_item ) right--; if ( left < right) swap(a, left, right); } } 34
Les tris Tris complexes § tri rapide (Quicksort) : Définition de la fonction d’échange void swap(Type. El *a, int l, int r) { Type. El t; t=a[l]; a[l]=a[r]; a[r]=t; } 4/4 35
Les tris Tris complexes § tri rapide (Quicksort) : § Meilleur cas : pivot = médiane § nb de comparaisons ? O(n log n) § nb de déplacements ? O(1) 36
Les tris Tris complexes § tri rapide (Quicksort) : § Pire cas : pivot = min. ou max. § nb de comparaisons ? O(n 2) § nb de déplacements ? O(n 2) 37
Les tris Tris complexes § tri rapide (Quicksort) : § Exemple – Trier en ordre alphabétique une séquence de chaînes de caractères entrées par clavier en utilisant la fonction standarde qsort (de la bibliothèque stdlib. h). #include <stdio. h> 1/2 #include <string. h> #include <stdlib. h> #define MAXMOTS 100 #define MAXCARS 3000 char espace[MAXCARS], *libre = espace; a et b sont des adresses de char *mots[MAXMOTS]; "chaînes" int nbr_mots = 0; int comparer(const void *a, const void *b) { /* Les arguments de cette fonction doivent être déclarés "void *" (voyez la */ /* déclaration de qsort). */ return strcmp(*(char **)a, *(char **)b); 38 }
Les tris Tris complexes § tri rapide (Quicksort) : § Exemple – Trier en ordre alphabétique une séquence de chaînes de caractères entrées par clavier en utilisant la fonction standarde qsort (de la bibliothèque stdlib. h). main() 2/2 { int i; while(puts ("Entrer une chainen"), gets(libre) != NULL && *libre != '