diff --git a/slides/cours_6.md b/slides/cours_6.md index 9761637ad62f49c75f34b12cd6dd421fce119018..6d5ec33de2c1f4814982b312d6e1ddc1e0fe9163 100644 --- a/slides/cours_6.md +++ b/slides/cours_6.md @@ -284,7 +284,7 @@ Et sur votre machine les résultats seront **différents**. * Nécessité d'avoir une mesure indépendante du/de la matériel/compilateur/façon de mesurer/météo. -# Analyse de complexité algorithmique (1/N) +# Analyse de complexité algorithmique (1/4) * On analyse le **temps** pris par un algorithme en fonction de la **taille de l'entrée**. @@ -303,7 +303,7 @@ bool in_list = is_present(N, sorted_list, elem); * l'élément est le premier de la liste (ou à une position toujours la même). * ce genre de cas pathologique ne rentre pas en ligne de compte. -# Analyse de complexité algorithmique (2/N) +# Analyse de complexité algorithmique (2/4) ## Recherche linéaire @@ -329,7 +329,7 @@ bool is_present(int n, int tab[], int elem) { La **complexité algorithmique** est proportionnelle à `N`: on double la taille du tableau $\Rightarrow$ on double le temps pris par l'algorithme. -# Analyse de complexité algorithmique (3/N) +# Analyse de complexité algorithmique (3/4) ## Recherche dichotomique @@ -351,7 +351,7 @@ bool is_present_binary_search(int n, int tab[], int elem) { } ``` -# Analyse de complexité algorithmique (4/N) +# Analyse de complexité algorithmique (4/4) ## Recherche dichotomique @@ -498,7 +498,7 @@ $$ swaps})=\mathcal{O}(N^2). $$ -# Tri par insertion (1/N) +# Tri par insertion (1/3) ## But @@ -511,7 +511,7 @@ triés du tableau.  -# Tri par insertion (2/N) +# Tri par insertion (2/3) ## Exercice: Proposer un algorithme @@ -531,7 +531,7 @@ void tri_insertion(int size, int tab[size]) { } ``` -# Tri par insertion (2/N) +# Tri par insertion (3/3) ## Question: Quelle est la complexité? @@ -545,7 +545,7 @@ void tri_insertion(int size, int tab[size]) { * 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/N) +# Tri rapide ou quicksort (1/8) ## Idée: algorithme `diviser pour régner` (`divide-and-conquer`) @@ -559,7 +559,7 @@ void tri_insertion(int size, int tab[size]) { 1. Éléments à gauche sont **plus petits** que le pivot. 2. Élements à droite sont **plus grands** que le pivot. -# Tri rapide ou quicksort (2/N) +# Tri rapide ou quicksort (2/8) ## Algorithme `quicksort(tableau)` @@ -578,43 +578,105 @@ Compris? Non c'est normal, faisons un exemple. -# Tri rapide ou quicksort (4/N) +# Tri rapide ou quicksort (4/8) Deux variables sont primordiales: ```C -int i, j; // les indices min/max des tableaux à trier +int low, high; // les indices min/max des tableaux à trier ``` -  -# Tri rapide ou quicksort (5/N) +# Tri rapide ou quicksort (5/8) Deux variables sont primordiales: ```C -int i, j; // les indices min/max des tableaux à trier +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/N) +# 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); + } + } +} ``` -## Remarques -* Le choix du pivot est arbitraire. - +# 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; +} +```