diff --git a/slides/cours_6.md b/slides/cours_6.md index 6d5ec33de2c1f4814982b312d6e1ddc1e0fe9163..8dcadfeee8017f561ed340c1d7523d2ee3dc5e39 100644 --- a/slides/cours_6.md +++ b/slides/cours_6.md @@ -498,185 +498,4 @@ $$ swaps})=\mathcal{O}(N^2). $$ -# Tri par insertion (1/3) - -## But - -* trier un tableau par ordre croissant - -## Algorithme - -Prendre un élément du tableau et le mettre à sa place parmis les éléments déjà -triés du tableau. - - - -# Tri par insertion (2/3) - -## Exercice: Proposer un algorithme - -. . . - -```C -void tri_insertion(int size, int tab[size]) { - for (int i = 1; i < size; i++) { - int pos = i; - int tmp = tab[i]; - while (pos > 0 && tab[pos - 1] > tmp) { - tab[pos] = tab[pos - 1]; - pos = pos - 1; - } - tab[pos] = tmp; - } -} -``` - -# Tri par insertion (3/3) - -## Question: Quelle est la complexité? - -. . . - -* Parcous de tous les éléments (ordre $N$); placer (ordre $N$). -* Moyenne: $\mathcal{O}(N^2)$. - -. . . - -* Pire des cas, liste triée à l'envers: $\mathcal{O}(N^2)$, -* Meilleurs des cas, liste déjà triée: $\mathcal{O}(N)$, - -# Tri rapide ou quicksort (1/8) - -## Idée: algorithme `diviser pour régner` (`divide-and-conquer`) - -* Diviser: découper un problème en sous problèmes; -* Régner: résoudre les sous-problèmes (souvent récursivement); -* Combiner: à partir des sous problèmes résolu, calculer la solution. - -## Le pivot - -* Trouver le **pivot**, un élément qui divise le tableau en 2, tels que: - 1. Éléments à gauche sont **plus petits** que le pivot. - 2. Élements à droite sont **plus grands** que le pivot. - -# Tri rapide ou quicksort (2/8) - -## Algorithme `quicksort(tableau)` - -1. Choisir le pivot et l'amener à sa place: - * Les éléments à gauche sont plus petits que le pivot. - * Les éléments à droite sont plus grand que le pivot. -2. `quisort(tableau_gauche)` en omettant le pivot. -3. `quisort(tableau_droite)` en omettant le pivot. -4. S'il y a moins de deux éléments dans le tableau, le tableau est trié. - -. . . - -Compris? - -. . . - -Non c'est normal, faisons un exemple. - -# Tri rapide ou quicksort (4/8) - -Deux variables sont primordiales: - -```C -int low, high; // les indices min/max des tableaux à trier -``` - - - -# Tri rapide ou quicksort (5/8) - -Deux variables sont primordiales: - -```C -int low, high; // les indices min/max des tableaux à trier -``` - -## Pseudocode: quicksort - -```C -void quicksort(array, low, high) { - if (less than 2 elems) { - pivot_ind = partition(array, low, high); - if (something left of pivot) - quicksort(array, low, pivot_ind - 1); - if (something right of pivot) - quicksort(array, pivot_ind + 1, high); - } -} -``` - -# Tri rapide ou quicksort (6/8) - -## Pseudocode: partition - -```C -int partition(array, low, high) { - pivot = array[high]; // choix arbitraire - i = first - 1; - j = last; - while i < j { - en remontant i trouver le premier élément > pivot; - en descendant j trouver le premier élément < pivot; - swap(array[i], array[j]); - // les plus grands à droite - // mettre les plus petits à gauche - } - // on met le pivot "au milieu" - swap(array[i], array[pivot]); - return i; // on retourne l'indice pivot -} -``` - -# Tri rapide ou quicksort (7/8) - -## Exercice: implémenter les fonctions `quicksort` et `partition` - -```C -void quicksort(int size, int array[size], int first, - int last) -{ - if (first < last) { - int midpoint = partition(size, array, first, last); - if (first < midpoint - 1) { - quicksort(size, array, first, midpoint - 1); - } - if (midpoint + 1 < last) { - quicksort(size, array, midpoint + 1, last); - } - } -} -``` - - -# Tri rapide ou quicksort (8/8) - -\footnotesize - -## Exercice: implémenter les fonctions `quicksort` et `partition` - -```C -int partition(int size, int array[size], int first, int last) { - int pivot = array[last]; - int i = first - 1, j = last; - do { - do { - i++; - } while (array[i] < pivot && i < j); - do { - j--; - } while (array[j] > pivot && i < j); - if (j > i) { - swap(&array[i], &array[j]); - } - } while (j > i); - swap(&array[i], &array[last]); - return i; -} -``` - diff --git a/slides/cours_7.md b/slides/cours_7.md new file mode 100644 index 0000000000000000000000000000000000000000..c20aeae02f016b1a26107445e8e54f610c904c43 --- /dev/null +++ b/slides/cours_7.md @@ -0,0 +1,222 @@ +--- +title: "Tris" +date: "2021-11-12" +patat: + eval: + tai: + command: fish + fragment: false + replace: true + ccc: + command: fish + fragment: false + replace: true + images: + backend: auto +... + + +# Tri par insertion (1/3) + +## But + +* trier un tableau par ordre croissant + +## Algorithme + +Prendre un élément du tableau et le mettre à sa place parmis les éléments déjà +triés du tableau. + + + +# Tri par insertion (2/3) + +## Exercice: Proposer un algorithme + +. . . + +```C +void tri_insertion(int size, int tab[size]) { + for (int i = 1; i < size; i++) { + int pos = i; + int tmp = tab[i]; + while (pos > 0 && tab[pos - 1] > tmp) { + tab[pos] = tab[pos - 1]; + pos = pos - 1; + } + tab[pos] = tmp; + } +} +``` + +# Tri par insertion (3/3) + +## Question: Quelle est la complexité? + +. . . + +* Parcous de tous les éléments (ordre $N$); placer (ordre $N$). +* Moyenne: $\mathcal{O}(N^2)$. + +. . . + +* Pire des cas, liste triée à l'envers: $\mathcal{O}(N^2)$, +* Meilleurs des cas, liste déjà triée: $\mathcal{O}(N)$, + +# Tri rapide ou quicksort (1/8) + +## Idée: algorithme `diviser pour régner` (`divide-and-conquer`) + +* Diviser: découper un problème en sous problèmes; +* Régner: résoudre les sous-problèmes (souvent récursivement); +* Combiner: à partir des sous problèmes résolu, calculer la solution. + +## Le pivot + +* Trouver le **pivot**, un élément qui divise le tableau en 2, tels que: + 1. Éléments à gauche sont **plus petits** que le pivot. + 2. Élements à droite sont **plus grands** que le pivot. + +# Tri rapide ou quicksort (2/8) + +## Algorithme `quicksort(tableau)` + +1. Choisir le pivot et l'amener à sa place: + * Les éléments à gauche sont plus petits que le pivot. + * Les éléments à droite sont plus grand que le pivot. +2. `quisort(tableau_gauche)` en omettant le pivot. +3. `quisort(tableau_droite)` en omettant le pivot. +4. S'il y a moins de deux éléments dans le tableau, le tableau est trié. + +. . . + +Compris? + +. . . + +Non c'est normal, faisons un exemple. + +# Tri rapide ou quicksort (4/8) + +Deux variables sont primordiales: + +```C +int low, high; // les indices min/max des tableaux à trier +``` + + + +# Tri rapide ou quicksort (5/8) + +Deux variables sont primordiales: + +```C +int low, high; // les indices min/max des tableaux à trier +``` + +## Pseudocode: quicksort + +```C +void quicksort(array, low, high) { + if (less than 2 elems) { + pivot_ind = partition(array, low, high); + if (something left of pivot) + quicksort(array, low, pivot_ind - 1); + if (something right of pivot) + quicksort(array, pivot_ind + 1, high); + } +} +``` + +# Tri rapide ou quicksort (6/8) + +## Pseudocode: partition + +```C +int partition(array, low, high) { + pivot = array[high]; // choix arbitraire + i = first - 1; + j = last; + while i < j { + en remontant i trouver le premier élément > pivot; + en descendant j trouver le premier élément < pivot; + swap(array[i], array[j]); + // les plus grands à droite + // mettre les plus petits à gauche + } + // on met le pivot "au milieu" + swap(array[i], array[pivot]); + return i; // on retourne l'indice pivot +} +``` + +# Tri rapide ou quicksort (7/8) + +## Exercice: implémenter les fonctions `quicksort` et `partition` + +```C +void quicksort(int size, int array[size], int first, + int last) +{ + if (first < last) { + int midpoint = partition(size, array, first, last); + if (first < midpoint - 1) { + quicksort(size, array, first, midpoint - 1); + } + if (midpoint + 1 < last) { + quicksort(size, array, midpoint + 1, last); + } + } +} +``` + + +# Tri rapide ou quicksort (8/8) + +\footnotesize + +## Exercice: implémenter les fonctions `quicksort` et `partition` + +```C +int partition(int size, int array[size], int first, int last) { + int pivot = array[last]; + int i = first - 1, j = last; + do { + do { + i++; + } while (array[i] < pivot && i < j); + do { + j--; + } while (array[j] > pivot && i < j); + if (j > i) { + swap(&array[i], &array[j]); + } + } while (j > i); + swap(&array[i], &array[last]); + return i; +} +``` + +# Tri à bulle (1/N) + +## Algorithme + +* Parcours du tableau et comparaison des éléments consécutifs: + - Si deux éléments consécutifs ne sont pas dans l'ordre, ils sont échangés. +* On recommence depuis le début du tableau jusqu'à avoir plus d'échanges à + faire. + +## Que peut-on dire sur le dernier élément du tableau après un parcours? + +. . . + +* Le plus grand élément est **à la fin** du tableau. + * Plus besoin de le traiter. +* A chaque parcours on s'arrête un élément plus tôt. + +# Tri à bulle (2/N) + +## Exemple + + +