Tris Introduction IFT 1025 Programmation 2 JianYun Nie









![Algorithme: par sélection Tri par sélection itératif: public void selection. Sort(int[] array) • int Algorithme: par sélection Tri par sélection itératif: public void selection. Sort(int[] array) • int](https://slidetodoc.com/presentation_image_h2/57dee0861688e1feef643113f2e675cc/image-10.jpg)
![Algorithme: par sélection public void selection. Sort(int[] array) { // Itération for (i=0; i<tab. Algorithme: par sélection public void selection. Sort(int[] array) { // Itération for (i=0; i<tab.](https://slidetodoc.com/presentation_image_h2/57dee0861688e1feef643113f2e675cc/image-11.jpg)
![Tri par sélection (récursif) public void selection. Sort(int[] array, int start. Index) { if Tri par sélection (récursif) public void selection. Sort(int[] array, int start. Index) { if](https://slidetodoc.com/presentation_image_h2/57dee0861688e1feef643113f2e675cc/image-12.jpg)
![Trouver min. Index (récursif) // trouver l’indexe de l’élément minimal public int min(int[] array, Trouver min. Index (récursif) // trouver l’indexe de l’élément minimal public int min(int[] array,](https://slidetodoc.com/presentation_image_h2/57dee0861688e1feef643113f2e675cc/image-13.jpg)
![Tri par sélection (récursif) void selection. Sort(int[] array, int start. Index) { if ( Tri par sélection (récursif) void selection. Sort(int[] array, int start. Index) { if (](https://slidetodoc.com/presentation_image_h2/57dee0861688e1feef643113f2e675cc/image-14.jpg)

![Tri par insertion (itératif) void insertion. Sort(int[] array, int start. Index) { for (int Tri par insertion (itératif) void insertion. Sort(int[] array, int start. Index) { for (int](https://slidetodoc.com/presentation_image_h2/57dee0861688e1feef643113f2e675cc/image-16.jpg)

![Tri par insertion (récursif) void insertion. Sort(int[] array, int start. Index) { if ( Tri par insertion (récursif) void insertion. Sort(int[] array, int start. Index) { if (](https://slidetodoc.com/presentation_image_h2/57dee0861688e1feef643113f2e675cc/image-18.jpg)






![merge. Sort public int[] merge. Sort(int [] array) { int [] array 1, array merge. Sort public int[] merge. Sort(int [] array) { int [] array 1, array](https://slidetodoc.com/presentation_image_h2/57dee0861688e1feef643113f2e675cc/image-25.jpg)
![Merge: fusionner deux ensembles triés public int [] merge(int[] array 1, int[] array 2) Merge: fusionner deux ensembles triés public int [] merge(int[] array 1, int[] array 2)](https://slidetodoc.com/presentation_image_h2/57dee0861688e1feef643113f2e675cc/image-26.jpg)
![quick. Sort public void quick. Sort(int[] array, int from, int to) { if (from quick. Sort public void quick. Sort(int[] array, int from, int to) { if (from](https://slidetodoc.com/presentation_image_h2/57dee0861688e1feef643113f2e675cc/image-27.jpg)

![partition public int partition(int[] array, int from, int to) { int pivot = array[from]; partition public int partition(int[] array, int from, int to) { int pivot = array[from];](https://slidetodoc.com/presentation_image_h2/57dee0861688e1feef643113f2e675cc/image-29.jpg)
![Partition (bis) public int partition(int[] array, int from, int to) { int pivot = Partition (bis) public int partition(int[] array, int from, int to) { int pivot =](https://slidetodoc.com/presentation_image_h2/57dee0861688e1feef643113f2e675cc/image-30.jpg)












![Trier d’autres données • Donnee [ ] array; • Arrays. sort(array) • Reflexion: – Trier d’autres données • Donnee [ ] array; • Arrays. sort(array) • Reflexion: –](https://slidetodoc.com/presentation_image_h2/57dee0861688e1feef643113f2e675cc/image-43.jpg)
- Slides: 43
Tris: Introduction IFT 1025: Programmation 2 Jian-Yun Nie
Trier les données • Créer un ordre dans les données – Ex. Ordre croissant, décroissant des valeurs numériques – Ordre croissant des mots, … • Pourquoi trier? – Faciliter la recherche (voir plus tard) – Faciliter la gestion en générale
Exemple • Trier en ordre croisant: 2, 56, 4, -7, 0, 78, -45, 10 • Une solution intuitive: – Prendre le plus petit suivant –… -45, -7, 0, 2, 4, 10, 56, 78 • Selection sort (Tri par sélection)
Principe Selection Sort • Pour un tableau: – Déterminer le plus petit élément p à partir de i – Échanger l’élément p avec i – Continuer à partir de i+1 2, 56, 4, -7, 0, 78, -45, 10 -45, 56, 4, -7, 0, 78, 2, 10 -45, -7, 4, 56, 0, 78, 2, 10 -45, -7, 0, 4, 56, 78, 2, 10 …
Tri par insertion • Pour un tableau – Prendre l’élément i – Insérer i dans l’ordre entre 0 et i – Continuer à partir de i+1 2, 56, 4, -7, 0, 78, -45, 10 2, 4, 56, -7, 0, 78, -45, 10 -7, 2, 4, 56, 0, 78, -45, 10 -7, 0, 2, 4, 56, 78, -45, 10
Tri par insertion (bis) • Pour un tableau – Prendre l’élément i – Insérer i dans l’ordre entre i et la fin – Continuer avec i-1 2, 56, 4, -7, 0, 78, -45, 10 2, 56, 4, -7, 0, -45, 10, 78 2, 56, 4, -7, -45, 0, 10, 78 2, 56, 4, -45, -7, 0, 10, 78 …
Principe général de tri • Diviser pour régner • Tri par sélection: – Diviser en deux parties (étape difficile) • Le plus petit élément • Le reste – Pour chaque partie divisée: • Trier séparément (récursion) – Fusionner les résultats • Plus petit + reste trié
Principe général de tri (bis) • Diviser pour régner • Tri par insertion: – Diviser en deux parties: • Le premier élément • Le reste – Pour chaque partie divisée: • Trier séparément (récursion) – Fusionner les résultats (étape difficile) • Insérer le premier élément dans le reste trié
Illustration Sélection Insertion 6 3 2 9 4 5 2 6 3 9 4 5 6 3 2 9 4 5 2 3 4 5 6 9 6 2 3 4 5 9 2 3 4 5 6 9
Algorithme: par sélection Tri par sélection itératif: public void selection. Sort(int[] array) • int min. Index, temp; // Itération • for (i=0; i<array. length-1; i++): // Trouver le plus petit élément à partir de i – min. Index=i; – for (j=i+1; j<array. length; j++): • if array[j]<array[min. Index] min. Index=j; // échanger i et min (swap(array, i, min. Index)) – if (min. Index != i) {temp=array[i]; array[i]=array[min. Index]; array[min. Index]=temp; }
Algorithme: par sélection public void selection. Sort(int[] array) { // Itération for (i=0; i<tab. length-1; i++) { // Trouver le plus petit élément à partir de i int min. Index = min(array, i); // échanger i et min –défini précédemment swap(array, i, min. Index) } }
Tri par sélection (récursif) public void selection. Sort(int[] array, int start. Index) { if ( start. Index >= array. length - 1 ) return; // Trouver min int min. Index = start. Index; for ( int index = start. Index + 1; index < array. length; index++ ) { if (array[index] < array[min. Index] ) min. Index = index; } // swap(array, start. Index, min. Index) // Récursion selection. Sort(array, start. Index + 1); }
Trouver min. Index (récursif) // trouver l’indexe de l’élément minimal public int min(int[] array, int start. Index) { int min. Reste; if ( start. Index >= array. length - 1 ) return start. Index; // trouver min pour le reste min. Reste = min(array, start. Index+1); // choisir entre start. Index et min. Reste if (array[start. Index]<array[min. Reste]) return start. Index; else return min. Reste; }
Tri par sélection (récursif) void selection. Sort(int[] array, int start. Index) { if ( start. Index >= array. length - 1 ) return; // Trouver min int min. Index = min(array, start. Index); // Swap swap(array, start. Index, min. Index); // Récursion selection. Sort(array, start. Index + 1); } swap(array, start. Index, min(array, start. Index))
Illustration selection. Sort(array, 0) 6 3 2 9 4 5 swap(0, min(array, 0)) 2 3 6 9 4 5 selection. Sort(array, 1) 2 3 4 5 6 9
Tri par insertion (itératif) void insertion. Sort(int[] array, int start. Index) { for (int i = 1; i < array. length; i++) { int next = array[i]; // de i-1 vers le début, décaler les éléments > a[i] int j = i; while (j > 0 && array[j - 1] > next) { array[j] = array[j - 1]; j--; } // Inserer l’élément array[j] = next; } }
Illustration 2, 56, 4, -7, 0, 78, -45, 10 2, 4, 56, -7, 0, 78, -45, 10 2, 4, 56*, 56, 0, 78, -45, 10 // de i-1 vers le début, décaler les éléments > a[i] i==3 2, 4*, 4, 56, 0, 78, -45, 10 a[i]==-7 2*, 2, 4, 56, 0, 78, -45, 10 next == -7 -7, 2, 4, 56, 0, 78, -45, 10 -7, 0, 2, 4, 56, 78, -45, 10 a[j] = next; . . .
Tri par insertion (récursif) void insertion. Sort(int[] array, int start. Index) { if ( start. Index >= array. length - 1 ) return; // Trier le reste insertion. Sort(array, start. Index + 1); // Insérer start. Index dans le reste insert(array, start. Index); }
Insérer // insérer l’élément index dans le reste qui est déjà trié public void insert(int [] array, int index) { if (index >= array. length-1) return; Arrêt de récursion if (array[index] <= array[index+1]) return; swap(array, index+1); //array[index]>array[index+1] insert(array, index+1); }
Illustration insert 6, 2, 3, 4, 5, 9 2, 6, 3, 4, 5, 9 2, 3, 6, 4, 5, 9 2, 3, 4, 6, 5, 9 2, 3, 4, 5, 6, 9 insert(array, 0) insert(array, 1) insert(array, 2) insert(array, 3) insert(array, 4) public void insert(int [] array, int index) { if (index >= array. length-1) return; if (array[index] < array[index+1]) return; swap(array, index+1); insert(array, index+1); }
Illustration: insertion. Sort 6 3 2 9 4 5 6 insertion. Sort(array, 0) 3 2 9 4 5 insertion. Sort(array, 1) 6 2 3 4 5 9 insert(array, 1) 2 3 4 5 6 9
merge. Sort et quick. Sort merge. Sort 5 3 2 9 4 6 quick. Sort 5 3 2 9 4 6 3 2 4 5 9 6 2 3 5 4 6 9 3 2 4 5 9 6 2 3 4 5 6 9
merge. Sort • Tri par fusion • Principe – Séparer l’ensemble de données en 2 parties de tailles comparables – Trier les 2 parties séparément – Fusionner les deux parties triées
quick. Sort • Principe – Déterminer un pivot au hasard (e. g. premier élément) – Séparer les données en 2 parties: • <= pivot • >= pivot – Trier les deux parties séparément – Mettre ensemble: <=pivot + (pivot) + >=pivot
merge. Sort public int[] merge. Sort(int [] array) { int [] array 1, array 2; // condition d’arrêt if (array. length <= 1) return; // séparer en 2 parties int[] first = new int[array. length / 2]; int[] second = new int[array. length - first. length]; System. arraycopy(array, 0, first. length); System. arraycopy(array, first. length, second, 0, second. length); // trier array 1 = merge. Sort(first); array 2 = merge. Sort(second); // fusionner return merge(array 1, array 2); } return merge(merge. Sort(first), merge. Sort(second))
Merge: fusionner deux ensembles triés public int [] merge(int[] array 1, int[] array 2) { int [] result = new int[array 1. length+array 2. length]; int i=0, j=0, k=0; // copier à chaque boucle celui qi est plus petit while (i<array 1. length && j<array 2. length) { if (array 1[i] < array 2[j]) { result[k]=array 1[i]; i++; } else { result[k]=array 2[j]; j++; } k++; } // copier ce qui reste dans array 1 ou array 2 if (i<array 1. length) System. arraycopy(array 1, i, result, k, array 1. length-i); if (j<array 2. length) System. arraycopy(array 2, j, result, k, array 2. length-j); return result; }
quick. Sort public void quick. Sort(int[] array, int from, int to) { if (from >= to) return; int p = partition(array, from, to); quick. Sort(array, from, p); quick. Sort(array, p + 1, to); }
partition
partition public int partition(int[] array, int from, int to) { int pivot = array[from]; int i = from - 1; int j = to + 1; while (i < j) { i++; while (array[i] < pivot) i++; j--; while (array[j] > pivot) j--; if (i < j) swap(array, i, j); } return j; }
Partition (bis) public int partition(int[] array, int from, int to) { int pivot = array[from]; int p = from; for (int r = from+1; r<=to; r++) <pivot >=pivot { if (array[r] < pivot) { 1 r 4 array[p] = array[r]; p 2 array[r] = array[p+1]; 3 array[p+1] = pivot; pivot p++; } return p; }
Qualité d’un algorithme • Efficacité – Utilisation de l’espace (octets, …) – Utilisation du temps (seconde, …) • Complexité asymptotique – Imaginons qu’il y a n données à traiter – Déterminer l’ordre de grandeur pour le nombre d’opérations et d’unité d’espace – Notation: O(n)
Complexité • Temps – Moyen – Pire cas • Ignorer la constante multiplicateur, constante et ordre inférieur – O(3 n)=O(n) – Dans une boucle, une opération v. s. 3 opérations – O(3 n+logn)=O(n) • Important: – Nombre de fois qu’on fait des boucles
Illustration Sélection 6 3 2 9 4 5 2 6 3 9 4 5 n éléments Pour choisir l’élément: n-1 comparaisons récursion 2 3 4 5 6 9 mettre ensemble: 1 opération
Selection sort (Décomposition) (n-1) + 1 (n-2) + 1 (n-3) + 1 … 1+1 • • n éléments n-1 éléments n-2 éléments n(n-1)/2 O(n 2) temps moyen = pire cas Espace: O(1)
Merge sort 5 3 2 9 4 6 • Séparer en 2 parties – 1 -2 opérations 5 3 2 9 4 6 2 3 5 4 6 9 • Trier les deux • Merge: 2 3 4 5 6 9 – n comparaisons
Merge sort (décomposition) 1 (séparer) + n (merge) = n+1 2 (séparer) + 2*n/2 (merges) = n+2 4 (séparer) + 4*n/4 (merges) = n+4 … 2 logn (séparer) + 2 logn*n/2 logn (merges) = n+n • Global: O(n logn) • Cas moyen = pire cas • Espace: O(n) • Reflexions: – Temps pour insertion. Sort et quick. Sort? – Espace? logn
Temps typiques pour le tri Time n 2 n log n 10 100 10, 000 200 1000 1, 000 3000
Comparaison n 10, 000 Merge sort (ms) 31 Selection sort (ms) 772 20, 000 47 3, 051 30, 000 62 6, 846 40, 000 80 12, 188 50, 000 97 19, 015 60, 000 113 27, 359
Comparaison
java. util. Arrays • Provides static methods for dealing with arrays. • Works for arrays of numbers, Strings, (and “comparable” Objects). • Methods: int pos = Arrays. binary. Search (arr, target); Arrays. sort (arr, from, to); //quicksort Arrays. fill (arr, value); // fills arr with a given value Arrays. fill (arr, from, to, value);
Trier d’autres types de données • Interface Comparable: – Méthode exigée: int compare. To(Object o) – Ordre: <0, <=0, ==0, >0 • Les classes qui implentent Comparable: Big. Decimal, Big. Integer, Byte. Buffer, Character, Char. Buffer, Charset, Collation. Key, Date, Double. Buffer, File, Float. Buffer, Integer, Long. Buffer, Object. Stream. Field, Short. Buffer, String, URI • E. g. String s: if (s. compare. To("Montreal")<0) …
Pour trier d’autres données class Donnee implements Comparable { … public int compare. To(Object d) { Donnee d 1 = (Donnee) d; … } }
Trier d’autres données • Donnee [ ] array; • Arrays. sort(array) • Reflexion: – Comment modifier les méthodes de tri pour fonctionner sur tout tableau (Array) du type Comparable? – public void insertion. Sort(Comparable [ ] array)