1 Les tris. 2 Traitement de données triées Le traitement de données déjà triées est plus...

42
1 Les tris

Transcript of 1 Les tris. 2 Traitement de données triées Le traitement de données déjà triées est plus...

Page 1: 1 Les tris. 2 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 dintervalles.

1

Les tris

Page 2: 1 Les tris. 2 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 dintervalles.

2

Les trisTraitement 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

Page 3: 1 Les tris. 2 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 dintervalles.

3

Les trisTri 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

Page 4: 1 Les tris. 2 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 dintervalles.

4

Les trisTris 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

Page 5: 1 Les tris. 2 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 dintervalles.

5

Les trisTris simples

tri par insertion :

44,55,12,42,94,18,06,674444,5512,44,5512,42,44,5512,42,44,55,9412,18,42,44,55,9406,12,18,42,44,55,9406,12,18,42,44,55,67,94

Page 6: 1 Les tris. 2 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 dintervalles.

6

Les trisTris simples

tri par insertion :

#include <stdio.h> 1/2#define CN 0#define OK 1typedef int TypeEl;void triInsertion(TypeEl tab[], int n, int * err);void main() { TypeEl x[]={44,55,12,42,94,18,6,67};

int nbr,i;nbr=sizeof(x)/sizeof(TypeEl);printf("Le tableau non trie\n");for(i=0;i<nbr;i++)

printf("%3d",x[i]);printf("\n");int err;triInsertion(x,nbr,&err);printf("Le tableau trie\n");for(i=0;i<nbr;i++)

printf("%3d",x[i]); }

Page 7: 1 Les tris. 2 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 dintervalles.

7

Les trisTris simples

tri par insertion :

void triInsertion(TypeEl 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;TypeEl 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;

}}

Page 8: 1 Les tris. 2 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 dintervalles.

8

Les trisTris simples

tri par insertion :

Le tableau non trie 44 55 12 42 94 18 6 67Le tableau trie 6 12 18 42 44 55 67 94

Page 9: 1 Les tris. 2 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 dintervalles.

9

Les trisTris 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(n2) nb de deplacements ? O(n2)

Page 10: 1 Les tris. 2 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 dintervalles.

10

Les trisTris 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

Page 11: 1 Les tris. 2 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 dintervalles.

11

Les trisTris simples

tri par sélection :

44,55,12,42,94,18,06,6706,55,12,42,94,18,44,6706,12,55,42,94,18,44,6706,12,18,42,94,55,44,6706,12,18,42,94,55,44,6706,12,18,42,44,55,94,6706,12,18,42,44,55,94,6706,12,18,42,44,55,67,9406,12,18,42,44,55,67,94

Page 12: 1 Les tris. 2 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 dintervalles.

12

Les trisTris simples

tri par sélection :

#include <stdio.h> 1/3#define CN 0#define OK 1typedef int TypeEl;void triSelection(TypeEl tab[], int n, int * err);void main() { TypeEl x[]={44,55,12,42,94,18,6,67};

int nbr,i;nbr=sizeof(x)/sizeof(TypeEl);printf("Le tableau non trie\n");for(i=0;i<nbr;i++)

printf("%3d",x[i]);printf("\n");int err;triSelection(x,nbr,&err);printf("Le tableau trie\n");for(i=0;i<nbr;i++)

printf("%3d",x[i]); }

Page 13: 1 Les tris. 2 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 dintervalles.

13

Les trisTris simples

tri par sélection :

void triSelection(TypeEl 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; TypeEl 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;}

}

Page 14: 1 Les tris. 2 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 dintervalles.

14

Les trisTris simples

tri par sélection :

/*x est l’élément minimum du sous-tableau non trié*/ 3/3 if (x != tab[i])

{ tab[pos] = tab[i]; tab[i] = x;}

} //fin de boucle for} //fin de la fonction

Le tableau non trie 44 55 12 42 94 18 6 67Le tableau trie 6 12 18 42 44 55 67 94

Page 15: 1 Les tris. 2 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 dintervalles.

15

Les trisTris 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

Page 16: 1 Les tris. 2 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 dintervalles.

16

Les trisTris simples

tri à bulles (Bubblesort) :

44,55,12,42,94,18,06,6706,44,55,12,42,94,18,6706,44,55,12,18,42,94,6706,44,55,12,18,42,94,6706,12,44,55,18,42,94,6706,12,44,55,18,42,67,9406,12,18,44,55,42,67,9406,12,18,42,44,55,67,9406,12,18,42,44,55,67,94

Page 17: 1 Les tris. 2 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 dintervalles.

17

Les trisTris simples

tri à bulles (Bubblesort) :

#include <stdio.h> 1/2#define CN 0#define OK 1typedef int TypeEl;void triBulles(TypeEl tab[], int n, int * err);void main() { TypeEl x[]={44,55,12,42,94,18,6,67};

int nbr,i;nbr=sizeof(x)/sizeof(TypeEl);printf("Le tableau non trie\n");for(i=0;i<nbr;i++)

printf("%3d",x[i]);printf("\n");int err;triBulles(x,nbr,&err);printf("Le tableau trie\n");for(i=0;i<nbr;i++)

printf("%3d",x[i]); }

Page 18: 1 Les tris. 2 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 dintervalles.

18

Les trisTris simples

tri à bulles (Bubblesort) :

void triBulles(TypeEl 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; TypeEl 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 67Le tableau trie 6 12 18 42 44 55 67 94

Page 19: 1 Les tris. 2 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 dintervalles.

19

Les trisTris simples

tri à bulles (Bubblesort) - amélioration

void triBulles(TypeEl tab[], int n, int * err){ int i, pos, change; TypeEl 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;}

pos++; }while(change);}

Amélioration consiste à arrêter le processus s'il n'y a aucun échange dans une passe

Page 20: 1 Les tris. 2 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 dintervalles.

20

Les trisTris 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).

Page 21: 1 Les tris. 2 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 dintervalles.

21

Les tris tri par fusion (merge sorting):

Le premier étape

Le deuxième étape

Page 22: 1 Les tris. 2 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 dintervalles.

22

Les trisTris simples

tri par fusion (merge sorting):

#include <stdio.h> 1/4void merge_sort(int in[],int a,int b,int out[]);void aff_tab(int in[],int k);void merge_array(int in1[],int in2[],int n1,int n2,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];printf("Le tableau non trie\n");aff_tab(in_tab,n);merge_sort(in_tab,0,n-1,out_tab);printf("Le tableau trie\n");aff_tab(out_tab,n);printf("Le nombre de comparaison est %d\n",compar);

}

Le tableau non trie3 1 4 1 5 9 2 6 5 4

Le tableau trie1 1 2 3 44 5 5 6 9Le nombre de comparaison est 22

Page 23: 1 Les tris. 2 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 dintervalles.

23

Les trisTris simples

tri par fusion (merge sorting):

void aff_tab(int in[],int k) 2/4 { int i;

for(i=1;i<=k;i++)printf("%d%c",in[i-1],i%5==0?'\n':' ');

printf("\n"); }

Définition de la fonction d’affichage

Page 24: 1 Les tris. 2 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 dintervalles.

24

Les trisTris simples

tri par fusion (merge sorting):

void merge_sort(int in[],int a,int b,int out[]) 3/4 { int m, out1[20], out2[20];

if(a==b) out[0]=in[a];else if(1==(b-a))

{ if ( in[a]<=in[b] ){ out[0]=in[a]; out[1]=in[b]; }

else{ out[0]=in[b]; out[1]=in[a]; }

compar++;}

else{ m=a+(b-a)/2;

merge_sort(in, a, m, out1); merge_sort(in, m+1, b, out2); merge_array(out1, out2, 1+m-a, b-m, out);

}}

Définition de la fonction merge_sort

Page 25: 1 Les tris. 2 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 dintervalles.

25

Les trisTris simples

tri par fusion (merge sorting):

void merge_array(int in1[],int in2[],int n1,int n2,int out[]) 4/4 { int i=0,j=0,k=0;

while ( (i<n1) && (j<n2) ) { if(in1[i] <= in2[j]) { out[k]=in1[i]; i++; }

else { out[k]=in2[j]; j++; }k++;compar++;

} if(i !=n1) do { out[k]=in1[i]; i++;

k++; } while(i<n1); else do { out[k]=in2[j];

j++;k++;

} while(j<n2); }

Définition de la fonction merge_array

Si on a des éléments dans les deux sous-tableaux

Si on n’a pas d’éléments dans un des deux sous-tableaux

Page 26: 1 Les tris. 2 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 dintervalles.

26

Les trisTris simples

tri panier (bucket sort) La grandeur de l’ensemble de base est petite, une

constante fixe m On utilise m compteurs

Page 27: 1 Les tris. 2 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 dintervalles.

27

Les trisTris 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.

Page 28: 1 Les tris. 2 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 dintervalles.

28

Les trisTris 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 chercher à 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 réduction.

Page 29: 1 Les tris. 2 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 dintervalles.

29

Les trisTris 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

Page 30: 1 Les tris. 2 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 dintervalles.

30

Les trisTris complexes

tri rapide (Quicksort) :

44,55,12,42,94,18,06,6744,55,12,42,94,18,06,67

44,55,12,42,94,18,06,67

06,55,12,42,94,18,44,67

06,55,12,42,94,18,44,67

06,18,12,42,94,55,44,67

06,18,12,42,94,55,44,67

Page 31: 1 Les tris. 2 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 dintervalles.

31

Les trisTris complexes

tri rapide (Quicksort) : 06,18,12,42,94,55,44,67

06,12,18,42,94,55,44,67

06,12,18,42,94,55,44,67

06,12,18,42,44,55,94,67

06,12,18,42,44,55,94,67

06,12,18,42,44,55,67,94

Page 32: 1 Les tris. 2 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 dintervalles.

32

Les trisTris complexes

tri rapide (Quicksort) : #include <stdio.h> 1/4

typedef int TypeEl;void swap(TypeEl *a,int l,int r);quicksort( TypeEl *a, int low, int high );void partition( TypeEl *a, int low, int high,int *pivot );void main() { TypeEl x[ ]={44,55,12,42,94,18,6,67};

int nbr,i;nbr=sizeof(x)/sizeof(TypeEl);printf("Le tableau non trie\n");for(i=0;i<nbr;i++)

printf("%3d",x[i]);printf("\n");quicksort(x,0,nbr-1);printf("Le tableau trie\n");for(i=0;i<nbr;i++)

printf("%3d",x[i]); }

Le tableau non trie 44 55 12 42 94 18 6 67Le tableau trie 6 12 18 42 44 55 67 94

Page 33: 1 Les tris. 2 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 dintervalles.

33

Les trisTris complexes

tri rapide (Quicksort) :

quicksort( TypeEl *a, int low, int high ) 2/4{

int pivot;/* condition terminale! */if ( high > low )

{ partition( a, low, high,& pivot ); quicksort( a, low, pivot-1 ); quicksort( a, pivot+1, high ); }}

Définition de la fonction quicksort

Page 34: 1 Les tris. 2 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 dintervalles.

34

Les trisTris complexes

tri rapide (Quicksort) : void partition( TypeEl *a, int low, int high, int *pivot) 3/4

{ int left, right;TypeEl pivot_item;*pivot = (low+high)/2;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);

} }

Définition de la fonction partition

Page 35: 1 Les tris. 2 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 dintervalles.

35

Les trisTris complexes

tri rapide (Quicksort) :

void swap(TypeEl *a,int l,int r) 4/4 { TypeEl t;

t=a[l]; a[l]=a[r]; a[r]=t; }

Définition de la fonction d’échange

Page 36: 1 Les tris. 2 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 dintervalles.

36

Les trisTris complexes

tri rapide (Quicksort) : Meilleur cas : pivot = médiane

nb de comparaisons ? O(n log n) nb de déplacements ? O(1)

Page 37: 1 Les tris. 2 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 dintervalles.

37

Les trisTris complexes

tri rapide (Quicksort) : Pire cas : pivot = min. ou max.

nb de comparaisons ? O(n2) nb de déplacements ? O(n2)

Page 38: 1 Les tris. 2 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 dintervalles.

38

Les trisTris 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 3000char espace[MAXCARS], *libre = espace;char *mots[MAXMOTS];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);}

a et b sont des adresses de "chaînes"

Page 39: 1 Les tris. 2 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 dintervalles.

39

Les trisTris 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 chaine\n"),gets(libre) != NULL && *libre != '\0')

{ mots[nbr_mots++] = libre;

libre += strlen(libre) + 1;}

qsort(mots, nbr_mots, sizeof(char *), comparer); for (i = 0; i < nbr_mots; i++)

printf("%s\n", mots[i]);}

Page 40: 1 Les tris. 2 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 dintervalles.

40

Les trisTris complexes

tri rapide (Quicksort) - problèmes:

1. 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 le plus grand des 2 sous-tableaux

O(1) <= taille de la pile <= O(log n) plutot que : O(1) <= taille de la pile <= O(n)

Page 41: 1 Les tris. 2 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 dintervalles.

41

Les trisTris complexes

tri rapide (Quicksort) - problèmes:1. Attention aux bornes:

3. Choix de pivot Comment choisir un bon pivot ?

Solution idéale : Trouver a chaque fois la valeur médiane du

sous - tableau a trier - sa recherche précise rend le tri plus lent que sans elle.

Solution quelquefois utilisée : Prendre par exemple trois valeurs, pour en

prendre la valeur médiane. La totalité de ces améliorations peut apporter un

gain de l'ordre de 20% par rapport à la version de base.

Page 42: 1 Les tris. 2 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 dintervalles.

42

Les trisTris complexes

tri par arbre (Treesort):

Algorithme Utiliser une structure d’arbre pour trier la séquence de

clés.