From 6bc81e4afebed7de8a04b33eafc20d9a81b00081 Mon Sep 17 00:00:00 2001 From: davy39 Date: Sun, 7 Apr 2024 17:53:00 +0200 Subject: [PATCH] maj Algo Tri --- docs/algo/proprietes.md | 2 +- docs/algo/tris/.pages | 2 +- docs/algo/tris/index.md | 24 ++-- docs/algo/tris/insertion.md | 116 +++++++++---------- docs/algo/tris/scripts/help_sorted test.py | 1 + docs/algo/tris/scripts/help_sorted_corr.py | 2 + docs/algo/tris/scripts/mini_depuis.py | 2 +- docs/algo/tris/scripts/mini_depuis_REM.md | 1 + docs/algo/tris/scripts/mini_depuis_corr.py | 6 + docs/algo/tris/scripts/mini_depuis_test.py | 4 + docs/algo/tris/scripts/selection.py | 2 +- docs/algo/tris/scripts/selection_bis_corr.py | 3 - docs/algo/tris/scripts/selection_corr.py | 5 + docs/algo/tris/scripts/selection_test.py | 15 +++ docs/algo/tris/scripts/tri_sel_effet_corr.py | 12 ++ docs/algo/tris/scripts/tri_selection_corr.py | 0 docs/algo/tris/selection.md | 93 ++++++--------- docs/ressources/index.md | 2 + docs/xtra/stylesheets/extra.css | 18 +++ 19 files changed, 169 insertions(+), 141 deletions(-) create mode 100644 docs/algo/tris/scripts/help_sorted test.py create mode 100644 docs/algo/tris/scripts/help_sorted_corr.py create mode 100644 docs/algo/tris/scripts/mini_depuis_REM.md create mode 100644 docs/algo/tris/scripts/mini_depuis_corr.py create mode 100644 docs/algo/tris/scripts/mini_depuis_test.py create mode 100644 docs/algo/tris/scripts/selection_corr.py create mode 100644 docs/algo/tris/scripts/selection_test.py create mode 100644 docs/algo/tris/scripts/tri_sel_effet_corr.py create mode 100644 docs/algo/tris/scripts/tri_selection_corr.py diff --git a/docs/algo/proprietes.md b/docs/algo/proprietes.md index 428543b64..1752212ad 100644 --- a/docs/algo/proprietes.md +++ b/docs/algo/proprietes.md @@ -328,7 +328,7 @@ - ??? example "Exemple" + ??? example "Exemples" Soit un algorithme qui demande en entrée le nombre $n$ de jours restant avant le bac, et qui prépare un élève au bac. ??? note "Complexité Constante" diff --git a/docs/algo/tris/.pages b/docs/algo/tris/.pages index b962561f1..eff227698 100644 --- a/docs/algo/tris/.pages +++ b/docs/algo/tris/.pages @@ -1,6 +1,6 @@ nav: - 1️⃣ Introduction au tri : index.md - - 1️⃣ Tri par insertion : insertion.md - 1️⃣ Tri par sélection : selection.md + - 1️⃣ Tri par insertion : insertion.md - 1️⃣ Exercices : exercices.md diff --git a/docs/algo/tris/index.md b/docs/algo/tris/index.md index 174f397c0..d4deb551f 100644 --- a/docs/algo/tris/index.md +++ b/docs/algo/tris/index.md @@ -8,7 +8,7 @@ -??? abstract "Le tri en informatique" +??? info "Intro : Le tri en informatique" Dans la vie courante, les deux verbes trier et classer ne sont pas synonymes. - **Trier** ou effectuer un tri c’est répartir les éléments en paquets correspondant à un certain critère : par exemple séparer les déchets selon leur nature, les personnes d’une assemblée selon leur sexe ou selon leur langue maternelle. @@ -21,18 +21,21 @@ !!! info "Définition à retenir" En informatique le **tri** est à prendre avec le sens de **classement**. -{{exercice(prem=1, titre="Algorithmes de tri")}} - Le lien suivant va nous aider à imaginer des algorithmes de tris en manipulant des cartes : - [Simulateur de jeu de cartes](https://deck.of.cards/){ .md-button target="_blank" rel="noopener" } +??? video "Vidéo : Les algorithmes de tri" + - 💡 Vous devez imaginer et expliquer une méthode qui permette de trier des cartes. Il y a beaucoup de méthodes possibles ! A vous d'en trouver au moins une ! +??? example "Animation : Différentes méthodes de tri" + Changer le *type de tri* et cliquer sur *commencer* pour visualiser les étapes de l'algorithme. + :warning: Seuls les tris par **insertion** et **sélection** sont au programme en NSI. + + -??? python "Le tri natif en Python avec `sorted`" +??? python "Astuce Python : tri natif avec `sorted()` et `sort()`" 👉 En Python, vous pourrez utiliser la fonction `sorted` === "`help(sorted)`" {{ IDE('scripts/help_sorted') }} @@ -45,12 +48,7 @@ - -??? abstract "Compléments" - - - 😊 Pour approfondir : [Interstices](https://interstices.info/les-algorithmes-de-tri/){ .md-button target="_blank" rel="noopener" } - - +??? abstract "Compléments" + Pour approfondir : [Interstices](https://interstices.info/les-algorithmes-de-tri/){ .md-button target="_blank" rel="noopener" } diff --git a/docs/algo/tris/insertion.md b/docs/algo/tris/insertion.md index 08c2d3eb9..eaf6fe15f 100644 --- a/docs/algo/tris/insertion.md +++ b/docs/algo/tris/insertion.md @@ -1,21 +1,27 @@ # Tri par insertion -??? abstract "Insérer la clef" +!!! abstract "Principe du tri par insertion"
- Pour un tableau `tab` de taille `n` -

-    pour i allant de 1 à n-1
+
+    **En résumé :**
+
+    L'opération, pour chaque position `i`, consiste à prendre l'éléments d'indice `i` (la clef) et à l'insérer à la bonne place dans le tableau des éléments d'indices `0` à`i - 1`. Ce processus assure que les `i` premiers éléments seront triés.  
+
+    On pourra donc recommencer avec l'élément suivant (la clef suivante à l'indice `i + 1`).
+
+    **Algorithme :** 
+
+    Pour un tableau `tab` de taille `n`
+    
+    
pour i allant de 1 à n-1
         clef ← tab[i]
         insérer la clef au bon endroit dans tab 
     
-??? info "Le tri par insertion en bref" - L'opération, pour chaque position `i`, consiste à prendre l'éléments d'indice `i` (la clef) et à l'insérer à la bonne place dans le tableau des éléments d'indices `0` à`i - 1`. Ce processus assure que les `i` premiers éléments seront triés. - On pourra donc recommencer avec l'élément suivant (la clef suivante à l'indice `i + 1`). @@ -64,11 +70,6 @@ --- - Il est important de s'attarder sur deux points : - - * à quels éléments est-il **indispensable** d'appliquer l'algorithme ? - * sous quelle condition peut-on décaler des éléments ? - ???+ question "À quels éléments est-il **indispensable** d'appliquer l'algorithme ?" === "Cocher la ou les affirmations correctes" @@ -146,6 +147,10 @@ ); + + + === "En python" + Avant de transcrire en Python l'algorithme, gardons à l'esprit que : * il n'est pas indispensable d'aborder **tous** les éléments du tableau, @@ -153,7 +158,6 @@ * la condition pour savoir s'il est possible de décaler des éléments est **double**, * lors de chaque décalage, on **duplique** un élément. - === "En python" Compléter la fonction `#!py tri_insertion` prenant en argument un `#!py tableau` et le triant **en place** à l'aide du tri par insertion. {{ IDE('scripts/insertion') }} @@ -259,36 +263,30 @@ - :x: Lors de la dernière itération, la dernière valeur remonte en première position. Il faut effectuer $19$ décalages - ???+ question "Quel est le "pire des cas?"" + ???+ question "Complexité dans le "pire des cas?"" ??? success "Solution" Le **pire des cas** est atteint lorsque le tableau est trié dans l'ordre décroissant. Dans ce cas, pour un tableau de $N$ valeurs : - **Dans le pire des cas** : + **Dans le pire des cas** : - * la boucle principale effectue $N-1$ itérations, - * la première boucle secondaire effectue $1$ décalage, - * la deuxième effectue $2$ décalages, - * la troisième $3$ décalages, - * ... - * la dernière boucle $N - 1$ décalages. + * la boucle principale effectue $N-1$ itérations, + * la première boucle secondaire effectue $1$ décalage, + * la deuxième effectue $2$ décalages, + * la troisième $3$ décalages, + * ... + * la dernière boucle $N - 1$ décalages. - On effectue donc au total $1 + 2 + 3 + \dots+(N-1)$ décalages. On retrouve la somme étudiée dans [cette page](../2_selection/#iii-complexite-du-tri-par-selection). Le coût de cet algorithme est donc **quadratique**. + On effectue donc au total $1 + 2 + 3 + \dots+(N-1)$ décalages. On retrouve la somme étudiée dans [cette page](../2_selection/#iii-complexite-du-tri-par-selection). Le coût de cet algorithme est donc **quadratique**. - !!! info "Dans le *meilleur* des cas ?" + ???+ question "Complexité dans le "meilleur des cas?"" + ??? success "Solution" - Dans le cas où le tableau est initialement trié dans l'ordre croissant, l'algorithme n'effectuera qu'une seule comparaison et aucun échange à chaque itération de la boucle principale. - - Le coût sera alors **linéaire**. + Dans le cas où le tableau est initialement trié dans l'ordre croissant, l'algorithme n'effectuera qu'une seule comparaison et aucun échange à chaque itération de la boucle principale. + + Le coût sera alors **linéaire**. - - !!! abstract "💚 A retenir" - - La complexité du tri par insertion est quadratique : **Le coût est quadratique**. - On se place en effet dans le pire des cas : celui où le tableau est trié dans l'ordre décroissant. - - {{exercice(titre="Mesures du temps de calcul")}} ??? note "On se place dans le pire des cas" @@ -369,45 +367,42 @@ Cela correspond bien à une complexité **quadratique** ??? info "Visulalisation du temps de calcul" - {{jupyter('/algo/notebooks/temps_tri_insertion.ipynb')}} + {{jupyter('/notebooks/temps_tri_insertion.ipynb')}} - -??? "Correction de l'algorithme de tri par insertion et invariant de boucle" - **Après la ième itération de la boucle for (boucle en i de l’algorithme fourni) les i premiers éléments sont triés.** - Cette propriété est un invariant de boucle pour le tri par insertion. - Cela se comprend aisément car dans chaque tour de boucle nous avions utilisé la fonction `insere` dont le rôle est de ranger les i premiers éléments de la liste par ordre croissant. - - 😀 Cet invariant de boucle prouve la correction du tri par insertion. +{{exercice(titre="Correction de l'algorithme de tri par insertion")}} -??? info "Terminaison de l'algorithme de tri par insertion" + Prouver la correction de l'algorithme à l'aide d'un invariant de boucle. - 😒 La procédure de tri par insertion contient une boucle while. + ??? success "Réponse" + *Après la ième itération de la boucle for (boucle en i de l’algorithme fourni) les i premiers éléments sont triés.* - A chaque fois qu'on écrit une boucle while, il faut s'interroger : est-on sûr que cette boucle va se terminer ? + Cette propriété est un invariant de boucle pour le tri par insertion. + Cela se comprend aisément car dans chaque tour de boucle nous avions utilisé la fonction `insere` dont le rôle est de ranger les i premiers éléments de la liste par ordre croissant. + + Cet invariant de boucle prouve la correction du tri par insertion. - Rien de pire qu'un programme qui ne se termine jamais... +{{exercice(titre="Terminaison de l'algorithme de tri par insertion")}} + Justifier la terminaison à l'aide d'un variant de boucle. - Cette boucle s'arrête quand l'une des 2 conditions est fausse, donc quand : + ??? success "Réponse" + La procédure de tri par insertion contient une boucle `while` :warning: : est-on sûr que cette boucle va se terminer ? - * `j <= 0` - * ou `tableau[j - 1] <= valeur_a_inserer` + Cette boucle s'arrête quand l'une des 2 conditions est fausse, donc quand : - ??? info "Le variant de boucle" + * `j <= 0` + * ou `tableau[j - 1] <= valeur_a_inserer` - 👀 regardons ce qu'il se passe en détail : Avant la boucle, `j` vaut `i` et `0 <= i 0, on entre donc dans la boucle. + Sinon, on démarre avec `j` > 0, on entre donc dans la boucle. Dans le corps de la boucle, `j` est décrémenté de 1. On a donc un entier positif qui décroît **strictement** à chaque itération. - Le mot strictement est ici crucial, car si ce n'était pas strictement, il se pourrait qu'on itère indéfiniment sans que `j` diminue, mais dans notre exemple, `j` diminue forcément. - Donc `j` finira par devenir négatif si on n'a pas été stoppé avant par l'autre condition. Ceci prouve que la boucle se termine. @@ -416,9 +411,11 @@ Ici, ce **variant de boucle** est une quantité qui décroît strictement et finit donc inévitablement par atteindre une valeur "plancher" qui assure la terminaison. -??? python "A mémoriser : l'algorithme du tri par insertion" - - ```python +??? mem "À retenir" + + - Le tri par insertion a une complexité **quadratique**, c'est à dire de l'ordre du carré de la taille de la liste à trier $N^2$ : $O(n^2)$ + + ```python title="Algorithme de tri par insertion" def tri_insertion(tableau): for i in range(1, len(tableau)): valeur_a_inserer = tableau[i] @@ -429,9 +426,4 @@ tableau[j] = valeur_a_inserer ``` -??? info "A mémoriser : la complexité du tri par insertion" - - Le tri par insertion a une complexité **quadratique**, c'est à dire de l'ordre du carré de la taille de la liste à trier. - - diff --git a/docs/algo/tris/scripts/help_sorted test.py b/docs/algo/tris/scripts/help_sorted test.py new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/docs/algo/tris/scripts/help_sorted test.py @@ -0,0 +1 @@ + diff --git a/docs/algo/tris/scripts/help_sorted_corr.py b/docs/algo/tris/scripts/help_sorted_corr.py new file mode 100644 index 000000000..4c907127d --- /dev/null +++ b/docs/algo/tris/scripts/help_sorted_corr.py @@ -0,0 +1,2 @@ +help(sorted) + diff --git a/docs/algo/tris/scripts/mini_depuis.py b/docs/algo/tris/scripts/mini_depuis.py index 2478e28fd..f447bfc35 100644 --- a/docs/algo/tris/scripts/mini_depuis.py +++ b/docs/algo/tris/scripts/mini_depuis.py @@ -2,7 +2,7 @@ def indice_minimum_depuis(tableau, i): i_mini = i ... - +# Tests assert indice_minimum_depuis([3, 8, 1, 5, 4], 0) == 2, "Erreur en partant de l'indice 0" assert indice_minimum_depuis([3, 8, 1, 5, 4], 1) == 2, "Erreur en partant de l'indice 1" assert indice_minimum_depuis([3, 8, 1, 5, 4], 2) == 2, "Erreur en partant de l'indice 2" diff --git a/docs/algo/tris/scripts/mini_depuis_REM.md b/docs/algo/tris/scripts/mini_depuis_REM.md new file mode 100644 index 000000000..cfdbfcec8 --- /dev/null +++ b/docs/algo/tris/scripts/mini_depuis_REM.md @@ -0,0 +1 @@ +Dans le cas où le minimum apparaît plusieurs fois, on aurait pu aussi retenir la dernière d'entre elles. Le fonctionnement général de l'algorithme aurait été similaire (mais il n'aurait plus été [*stable*](https://fr.wikipedia.org/wiki/Algorithme_de_tri#Tri_stable)) \ No newline at end of file diff --git a/docs/algo/tris/scripts/mini_depuis_corr.py b/docs/algo/tris/scripts/mini_depuis_corr.py new file mode 100644 index 000000000..64f1dd7c7 --- /dev/null +++ b/docs/algo/tris/scripts/mini_depuis_corr.py @@ -0,0 +1,6 @@ +def indice_minimum_depuis(tableau, i): + i_mini = i + for j in range(i + 1, len(tableau)): + if tableau[j] < tableau[i_mini]: + i_mini = j + return i_mini \ No newline at end of file diff --git a/docs/algo/tris/scripts/mini_depuis_test.py b/docs/algo/tris/scripts/mini_depuis_test.py new file mode 100644 index 000000000..385eadabd --- /dev/null +++ b/docs/algo/tris/scripts/mini_depuis_test.py @@ -0,0 +1,4 @@ +assert indice_minimum_depuis([3, 8, 1, 5, 4], 0) == 2, "Erreur en partant de l'indice 0" +assert indice_minimum_depuis([3, 8, 1, 5, 4], 1) == 2, "Erreur en partant de l'indice 1" +assert indice_minimum_depuis([3, 8, 1, 5, 4], 2) == 2, "Erreur en partant de l'indice 2" +assert indice_minimum_depuis([3, 8, 1, 5, 4], 4) == 4, "Erreur en partant de l'indice 4" diff --git a/docs/algo/tris/scripts/selection.py b/docs/algo/tris/scripts/selection.py index 6da4ce82b..439ba0a63 100644 --- a/docs/algo/tris/scripts/selection.py +++ b/docs/algo/tris/scripts/selection.py @@ -13,7 +13,7 @@ def indice_minimum_depuis(tableau, i): def tri_selection(tableau): ... - +# Tests tableau_0 = [3, 1, 2] tri_selection(tableau_0) assert tableau_0 == [1, 2, 3], "Erreur avec [3, 1, 2]" diff --git a/docs/algo/tris/scripts/selection_bis_corr.py b/docs/algo/tris/scripts/selection_bis_corr.py index f58cca067..57a9a570b 100644 --- a/docs/algo/tris/scripts/selection_bis_corr.py +++ b/docs/algo/tris/scripts/selection_bis_corr.py @@ -6,6 +6,3 @@ def tri_selection(tableau): i_mini = j tableau[i], tableau[i_mini] = tableau[i_mini], tableau[i] - - - diff --git a/docs/algo/tris/scripts/selection_corr.py b/docs/algo/tris/scripts/selection_corr.py new file mode 100644 index 000000000..5cac8382a --- /dev/null +++ b/docs/algo/tris/scripts/selection_corr.py @@ -0,0 +1,5 @@ +def tri_selection(tableau): + for i in range(len(tableau) - 1): + i_mini = indice_minimum_depuis(tableau, i) + echange(tableau, i, i_mini) + diff --git a/docs/algo/tris/scripts/selection_test.py b/docs/algo/tris/scripts/selection_test.py new file mode 100644 index 000000000..cbadcac2e --- /dev/null +++ b/docs/algo/tris/scripts/selection_test.py @@ -0,0 +1,15 @@ +tableau_0 = [3, 1, 2] +tri_selection(tableau_0) +assert tableau_0 == [1, 2, 3], "Erreur avec [3, 1, 2]" + +tableau_1 = [1, 2, 3, 4] +tri_selection(tableau_1) +assert tableau_1 == [1, 2, 3, 4], "Erreur avec [1, 2, 3, 4]" + +tableau_2 = [-2, -5] +tri_selection(tableau_2) +assert tableau_2 == [-5, -2], "Erreur avec des valeurs négatives" + +tableau_4 = [] +tri_selection(tableau_4) +assert tableau_4 == [], "Erreur avec un tableau vide" diff --git a/docs/algo/tris/scripts/tri_sel_effet_corr.py b/docs/algo/tris/scripts/tri_sel_effet_corr.py new file mode 100644 index 000000000..7c3dd7f51 --- /dev/null +++ b/docs/algo/tris/scripts/tri_sel_effet_corr.py @@ -0,0 +1,12 @@ +def tri_selection(tableau): + for i in range(len(tableau) - 1): + i_mini = i + for j in range(i + 1, len(tableau)): + if tableau[j] < tableau[i_mini]: + i_mini = j + tableau[i], tableau[i_mini] = tableau[i_mini], tableau[i] + +valeurs = [5, 1, 2] +print("valeurs = ", valeurs) +tri_selection(valeurs) # Appel de la fonction avec l'argument [5, 1, 2] +print("Après appel de la fonction de tri : valeurs = ", valeurs) diff --git a/docs/algo/tris/scripts/tri_selection_corr.py b/docs/algo/tris/scripts/tri_selection_corr.py new file mode 100644 index 000000000..e69de29bb diff --git a/docs/algo/tris/selection.md b/docs/algo/tris/selection.md index b84b1aed6..97af997cc 100644 --- a/docs/algo/tris/selection.md +++ b/docs/algo/tris/selection.md @@ -1,23 +1,16 @@ # Tri par sélection -???+ abstract "Le tri par sélection en bref" +???+ abstract "Principe du tri par sélection"
+ **En résumé :** + * On cherche la valeur minimale et on la place au début du tableau. * On recommence à partir de la deuxième valeur, et on la place en deuxième position par échange. * Ainsi de suite - Le tri par sélection est l'un des plus simples à comprendre. Il est même probable que vous l'ayez déjà mis en application. - - Supposons que vous ayez des cartes à jouer en main et que vous souhaitiez les trier dans l'ordre croissant. Vous pouvez : - - * Parcourir du regard l'ensemble des cartes et déterminer laquelle est la plus petite, - - * Échanger cette carte minimale avec la première carte de votre main, - * Recommencer en cherchant la carte minimale à partir de la deuxième carte et l'échanger avec celle-ci, - * Recommencer à partir de la troisième carte *etc*. {{exercice(prem=1, titre="Déroulé « *à la main* »")}} === "Principe" @@ -80,6 +73,7 @@ {{exercice(titre="Tri par sélection en Python")}} L'une des étapes essentielles du tri par sélection est donc de déterminer l'indice de la valeur minimale à partir d'un certain indice `i`. Cette recherche ayant lieu à plusieurs reprises, nous allons utiliser une fonction pour la réaliser. + === "Fonction `#!py indice_minimum_depuis`" Compléter la fonction `#!py indice_minimum_depuis` prenant en argument un `#!py tableau` ainsi qu'un indice `#!py i` et renvoyant l'indice de la valeur minimale parmi les éléments situés après celui d'indice `#!py i` (inclus). @@ -90,18 +84,8 @@ {{ IDE('scripts/mini_depuis') }} - ??? success "Solution" - ```python - def indice_minimum_depuis(tableau, i): - i_mini = i - for j in range(i + 1, len(tableau)): - if tableau[j] < tableau[i_mini]: - i_mini = j - return i_mini - ``` - Dans le cas où le minimum apparaît plusieurs fois, on aurait pu aussi retenir la dernière d'entre elles. Le fonctionnement général de l'algorithme aurait été similaire (mais il n'aurait plus été [*stable*](https://fr.wikipedia.org/wiki/Algorithme_de_tri#Tri_stable)) === "Fonction `#!py tri_selection`" On donne les fonctions `#!py echange` et `#!py indice_minimum_depuis`. @@ -112,14 +96,6 @@ {{ IDE('scripts/selection') }} - ??? success "Solution" - - ```python - def tri_selection(tableau): - for i in range(len(tableau) - 1): - i_mini = indice_minimum_depuis(tableau, i) - echange(tableau, i, i_mini) - ``` === "Fonction `#!py tri_selection` (bis)" @@ -134,29 +110,27 @@ {{ IDE('scripts/selection_bis') }} - === "Utilisation" - ??? question "Tester le tri par sélection" - - Tester ci-dessous. Que s'est-il passé ? + === "Utilisation #1" + Tester ci-dessous. Que se passe-t-il ? - {{ IDE('scripts/tri_selection') }} - - ??? success "Solution" + ??? success "Réponse" + La fonction n'a pas de `return`, c'est une procédure. Elle renvoie donc `None` + + {{ IDE('scripts/tri_selection') }} - La fonction n'a pas de `return`, c'est une procédure. Elle renvoie donc `None` - ??? question "Que fait la fonction de tri par sélection ?" - Tester ci-dessous. Que s'est-il passé ? + === "Utilisation #2" + Tester ci-dessous. Que se passe-t-il ? - {{ IDE('scripts/tri_sel_effet') }} - - ??? success "Solution" + ??? success "Réponse" + La liste de départ a été modifiée ... - La liste de départ a été modifiée ... + C'est ce qu'on appelle un **effet de bord**. La fonction a modifié **"en place"** la liste. - C'est ce qu'on appelle un **effet de bord**. La fonction a modifié **"en place"** la liste. + {{ IDE('scripts/tri_sel_effet') }} + {{exercice(titre="Complexité du tri par sélection")}} Nous allons étudier le tri de `[9, 5, 8, -2, 6, 4]`. Nous avons mis en vert la partie triée de la liste. La dernière colonne donne le nombre de comparaisons effectuées par la fonction `rechercher_position_du_min`. @@ -225,10 +199,6 @@ La dernière ligne du tableau contient $n-1$ fois le terme $n$. On a donc $2 \times C(n)=(n-1)n$ , et donc $C(n)=\dfrac{(n-1)n}{2}$ -!!! abstract "💚 A retenir" - - La complexité du tri par sélection est quadratique : **Le coût est quadratique**. - {{exercice(titre="Mesures du temps de calcul")}} ??? question "Quel est le "pire des cas?"" ??? success "Solution" @@ -296,18 +266,22 @@ Cela correspond bien à une complexité **quadratique** -{{exercice(titre="Visulalisation du temps de calcul du tri par insertion")}} - {{jupyter('/algo/notebooks/temps_tri_selection.ipynb')}} +{{exercice(titre="Visualisation du temps de calcul du tri par sélection")}} + {{jupyter('/notebooks/temps_tri_selection.ipynb')}} + + +{{exercice(titre="Correction de l'algorithme de tri par sélection")}} -??? abstract "Correction de l'algorithme de tri par sélection" - ??? info "Invariant de boucle" + Démontrer, par récurrence, la correction de l'algorithme de tri par sélection. + + !!! info "Rappel sur les invariant de boucle" On appelle invariant d’une boucle une propriété qui, si elle est vraie avant l’exécution d’une itération, le demeure après l’exécution de l’itération. Un invariant de boucle bien choisi permet de prouver qu’une boucle produit le résultat attendu (correction). - ??? info "Correction de l'algorithme" + ??? success "Réponse" **Après la ième itération (boucle en i de l’algorithme fourni) les i premiers éléments sont triés.** **a. Vérifions sur l'exemple du tri de : `[9, 5, 8, -2, 6, 4] `** @@ -330,11 +304,15 @@ On prouve ainsi de proche en proche que pour n’importe quel entier i, après la ième itération, les i premiers éléments sont triés. Cela prouve la correction de l’algorithme de tri par sélection, car après n itérations une liste de longueur n est donc triée. -??? info "Terminaison de l'algorithme de tri par sélection" - L’algorithme de tri par sélection se termine car il a un nombre limité de tours de boucles, car il ne comporte que des boucles Pour. -??? abstract "A mémoriser : l'algorithme du tri par sélection" - ```python + +??? mem "A retenir" + + - La **complexité** du tri par sélection est **quadratique** : $O(n^2)$ + + - L’algorithme de tri par sélection **se termine** car il a un nombre limité de tours de boucles, du fait qu'il ne comporte que des boucles Pour qui sont des **boucles bornées**. + + ```python title="Algorithme du tri par sélection" def tri_selection(tableau): for i in range(len(tableau) - 1): i_mini = i @@ -343,6 +321,3 @@ i_mini = j tableau[i], tableau[i_mini] = tableau[i_mini], tableau[i] ``` - -??? abstract "A mémoriser : la complexité du tri par sélection" - Le tri par sélection a une complexité **quadratique**, c'est à dire de l'ordre du carré de la taille de la liste à trier. diff --git a/docs/ressources/index.md b/docs/ressources/index.md index dd40b35ef..907916c53 100755 --- a/docs/ressources/index.md +++ b/docs/ressources/index.md @@ -97,6 +97,8 @@ hide: - [Quentin Konieczko](https://www.youtube.com/@qkzk/videos) - Les vidéos de la chaine **Crash Courses** + - Les vidéos de **Cédric Gerland** [lien]( + https://www.youtube.com/@cedricgerland7621/videos) === "Tutoriels" Pour apprendre les bases du langage de programmation **python**, une application en français est accessible à l'addresse : https://fr.futurecoder.io diff --git a/docs/xtra/stylesheets/extra.css b/docs/xtra/stylesheets/extra.css index e3657247e..ea8bb5cd2 100755 --- a/docs/xtra/stylesheets/extra.css +++ b/docs/xtra/stylesheets/extra.css @@ -97,6 +97,24 @@ strong { mask-image: var(--md-admonition-icon--video); } +/* Admonition A mémoriser */ +:root { + --md-admonition-icon--mem: url('data:image/svg+xml;charset=utf-8,') +} +.md-typeset .admonition.mem, +.md-typeset details.mem { + border-color: #AA8ED6; +} +.md-typeset .mem > .admonition-title, +.md-typeset .mem > summary { + background-color: #aa8ed64b; +} +.md-typeset .mem > .admonition-title::before, +.md-typeset .mem > summary::before { + background-color: #AA8ED6; + -webkit-mask-image: var(--md-admonition-icon--mem); + mask-image: var(--md-admonition-icon--mem); +}