From 72a68979c36f23066b4baa07ed0539f54a9d3ae5 Mon Sep 17 00:00:00 2001 From: Orestis <orestis.malaspinas@pm.me> Date: Mon, 18 Mar 2024 15:18:34 +0100 Subject: [PATCH] conflicts --- slides/cours_17.md | 956 -------------------------- slides/cours_18.md | 1606 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1606 insertions(+), 956 deletions(-) create mode 100644 slides/cours_18.md diff --git a/slides/cours_17.md b/slides/cours_17.md index 81085e4..970683f 100644 --- a/slides/cours_17.md +++ b/slides/cours_17.md @@ -406,959 +406,3 @@ flowchart TB; ::: -# Le pseudo-code de la suppression - -## Pour une feuille ou absent (ensemble) - -``` -arbre suppression(arbre, clé) - sous_arbre = position(arbre, clé) - si est_vide(sous_arbre) ou clé(sous_arbre) != clé - retourne vide - sinon - si est_feuille(sous_arbre) et clé(sous_arbre) == clé - nouvelle_feuille = parent(arbre, sous_arbre) - si est_vide(nouvelle_feuille) - arbre = vide - sinon - si gauche(nouvelle_feuille) == sous_arbre - gauche(nouvelle_feuille) = vide - sinon - droite(nouvelle_feuille) = vide - retourne sous_arbre -``` - -# Il nous manque le code pour le `parent` -## Pseudo-code pour trouver le parent (5min -> matrix) - -. . . - -``` -arbre parent(arbre, sous_arbre) - si est_non_vide(arbre) - actuel = arbre - parent = actuel - clé = clé(sous_arbre) - faire - si (clé != clé(actuel)) - parent = actuel - si clé < clé(actuel) - actuel = gauche(actuel) - sinon - actuel = droite(actuel) - sinon - retour parent - tant_que (actuel != sous_arbre) - retourne vide -``` - -# Le pseudo-code de la suppression - -\footnotesize - -## Pour un seul enfant (5min -> matrix) - -. . . - -``` -arbre suppression(arbre, clé) - sous_arbre = position(arbre, clé) - si est_vide(gauche(sous_arbre)) ou est_vide(droite(sous_arbre)) - parent = parent(arbre, sous_arbre) - si est_vide(gauche(sous_arbre)) - si droite(parent) == sous_arbre - droite(parent) = droite(sous_arbre) - sinon - gauche(parent) = droite(sous_arbre) - sinon - si droite(parent) == sous_arbreou est_ - droite(parent) = gauche(sous_arbre) - sinon - gauche(parent) = gauche(sous_arbre) - retourne sous_arbre -``` - - -# Le pseudo-code de la suppression - -\footnotesize - -## Pour au moins deux enfants (ensemble) - -``` -arbre suppression(arbre, clé) - sous_arbre = position(arbre, clé) # on revérifie pas que c'est bien la clé - si est_non_vide(gauche(sous_arbre)) et est_non_vide(droite(sous_arbre)) - max_gauche = position(gauche(sous_arbre), clé) - échange(clé(max_gauche), clé(sous_arbre)) - suppression(gauche(sous_arbre), clé) -``` - -# Exercices (poster sur matrix) - -1. Écrire le pseudo-code de l'insertion purement en récursif. - -. . . - -``` -arbre insertion(arbre, clé) - si est_vide(arbre) - retourne nœud(clé) - - si (clé < arbre->clé) - gauche(arbre) = insert(gauche(arbre), clé) - sinon - droite(arbre) = insert(droite(arbre), clé) - retourne arbre -``` - -# Exercices (poster sur matrix) - -2. Écrire le pseudo-code de la recherche purement en récursif. - -. . . - -``` -bool recherche(arbre, clé) - si est_vide(arbre) - retourne faux // pas trouvée - si clé(arbre) == clé - retourne vrai // trouvée - si clé < clé(arbre) - retourne recherche(gauche(arbre), clé) - sinon - retourne recherche(droite(arbre), clé) -``` - -# Exercices (à la maison) - -3. Écrire une fonction qui insère des mots dans un arbre et ensuite affiche - l'arbre. - -# Trier un tableau à l'aide d'un arbre binaire - -* Tableau représenté comme un arbre binaire. -* Aide à comprendre "comment" trier, mais on ne construit jamais l'arbre. -* Complexité $O(N\log_2 N)$ en moyenne et grande stabilité (pas de cas - dégénérés). - -# Lien entre arbre et tableau - -* La racine de l'arbre set le premier élément du tableau. -* Les deux fils d'un nœud d'indice $i$, ont pour indices $2i+1$ et $2i+2$: - * Les fils du nœud $i=0$, sont à $2\cdot 0+1=1$ et $2\cdot 0+2=2$. - * Les fils du nœud $i=1$, sont à $2\cdot 1+1=3$ et $2\cdot 1+2=4$. - * Les fils du nœud $i=2$, sont à $2\cdot 2+2=5$ et $2\cdot 1+2=6$. - * Les fils du nœud $i=3$, sont à $2\cdot 3+1=7$ et $2\cdot 3+2=8$. -* Un élément d'indice $i$ a pour parent l'élément $(i-1)/2$ (division entière): - * Le parent du nœud $i=8$ est $(8-1)/2=3$. - * Le parent du nœud $i=7$ est $(7-1)/2=3$. - -# Visuellement - -::: columns - -:::: column - -* Où vont les indices correspondant du tableau? - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0(( ))-->id1(( )); - id0-->id2(( )); - id1-->id3(( )); - id1-->id4(( )); - id2-->id5(( )); - id2-->id6(( )); - id3-->id7(( )); - id3-->id8(( )); - id4-->id9(( )); - id4-->id10(( )); - style id10 fill:#fff,stroke:#fff -``` -:::: - -:::: column - -* Les flèche de gauche à droite, parent -> enfants. -* Les flèche de droite à gauche, enfants -> parent. - - - -:::: - -::: - -**Propriétés:** - -1. les feuilles sont toutes sur l'avant dernier ou dernier niveau. -2. les feuilles de profondeur maximale sont "tassée" à gauche. - -# Le tas (ou heap) - -## Définition - -* Un arbre est un tas, si la valeur de chacun de ses descendants est inférieure - ou égale à sa propre valeur. - -## Exemples (ou pas) - -``` -16 8 14 6 2 10 12 4 5 # Tas -16 14 8 6 2 10 12 4 5 # Non-tas, 10 > 8 et 12 > 8 -``` - -## Exercices (ou pas) - -``` -19 18 12 12 17 1 13 4 5 # Tas ou pas tas? -19 18 16 12 17 1 12 4 5 # Tas ou pas tas? -``` - -. . . - -``` -19 18 12 12 17 1 13 4 5 # Pas tas! 13 > 12 -19 18 16 12 17 1 12 4 5 # Tas! -``` - -# Exemple de tri par tas (1/N) - -``` - | 1 | 16 | 5 | 12 | 4 | 2 | 8 | 10 | 6 | 7 | -``` - -::: columns - -:::: column - -* Quel est l'arbre que cela représente? - -. . . - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((1))-->id1((16)); - id0-->id2((5)); - id1-->id3((12)); - id1-->id4((4)); - id2-->id5((2)); - id2-->id6((8)); - id3-->id7((10)); - id3-->id8((6)); - id4-->id9((7)); - id4-->id10(( )); - style id10 fill:#fff,stroke:#fff -``` - -:::: - -:::: column - -**But:** Transformer l'arbre en tas. - -* On commence à l'indice $N/2 = 5$: `4`. -* `7 > 4` (enfant `>` parent). -* intervertir `4` et `7`. - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((1))-->id1((16)); - id0-->id2((5)); - id1-->id3((12)); - id1-->id4((7)); - id2-->id5((2)); - id2-->id6((8)); - id3-->id7((10)); - id3-->id8((6)); - id4-->id9((4)); - id4-->id10(( )); - style id10 fill:#fff,stroke:#fff -``` - -:::: - -::: - -. . . - -``` - * * - | 1 | 16 | 5 | 12 | 7 | 2 | 8 | 10 | 6 | 4 | -``` - -# Exemple de tri par tas (2/N) - -``` - | 1 | 16 | 5 | 12 | 7 | 2 | 8 | 10 | 6 | 4 | -``` - -::: columns - -:::: column - -**But:** Transformer l'arbre en tas. - -* On continue à l'indice $N/2-1 = 4$: `12`. -* Déjà un tas, rien à faire. - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((1))-->id1((16)); - id0-->id2((5)); - id1-->id3((12)); - id1-->id4((7)); - id2-->id5((2)); - id2-->id6((8)); - id3-->id7((10)); - id3-->id8((6)); - id4-->id9((4)); - id4-->id10(( )); - style id10 fill:#fff,stroke:#fff -``` - -:::: - -:::: column - -**But:** Transformer l'arbre en tas. - -* On continue à l'indice $N/2-2 = 3$: `5`. -* `5 < 8`, échanger `8` et `5` (aka `max(2, 5, 8)`) - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((1))-->id1((16)); - id0-->id2((8)); - id1-->id3((12)); - id1-->id4((7)); - id2-->id5((2)); - id2-->id6((5)); - id3-->id7((10)); - id3-->id8((6)); - id4-->id9((4)); - id4-->id10(( )); - style id10 fill:#fff,stroke:#fff -``` - -:::: - -::: - -. . . - -``` - | 1 | 16 | 8 | 12 | 7 | 2 | 5 | 10 | 6 | 4 | -``` - -# Exemple de tri par tas (3/N) - -``` - | 1 | 16 | 5 | 12 | 7 | 2 | 8 | 10 | 6 | 4 | -``` - -::: columns - -:::: column - -**But:** Transformer l'arbre en tas. - -* Indice $N/2-1 = 4$: `12`. -* Déjà un tas, rien à faire. - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((1))-->id1((16)); - id0-->id2((5)); - id1-->id3((12)); - id1-->id4((7)); - id2-->id5((2)); - id2-->id6((8)); - id3-->id7((10)); - id3-->id8((6)); - id4-->id9((4)); - id4-->id10(( )); - style id10 fill:#fff,stroke:#fff -``` - -:::: - -:::: column - -**But:** Transformer l'arbre en tas. - -* Indice $N/2-2 = 3$: `5`. -* `5 < 8`, `5 <=> max(2, 5, 8)` - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((1))-->id1((16)); - id0-->id2((8)); - id1-->id3((12)); - id1-->id4((7)); - id2-->id5((2)); - id2-->id6((5)); - id3-->id7((10)); - id3-->id8((6)); - id4-->id9((4)); - id4-->id10(( )); - style id10 fill:#fff,stroke:#fff -``` - -:::: - -::: - -``` - * * - | 1 | 16 | 8 | 12 | 7 | 2 | 5 | 10 | 6 | 4 | -``` - -# Exemple de tri par tas (4/N) - -``` - | 1 | 16 | 8 | 12 | 7 | 2 | 5 | 10 | 6 | 4 | -``` - -::: columns - -:::: column - -**But:** Transformer l'arbre en tas. - -* Indice $N/2-3 = 1$: `16`. -* Déjà un tas, rien à faire. - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((1))-->id1((16)); - id0-->id2((8)); - id1-->id3((12)); - id1-->id4((7)); - id2-->id5((2)); - id2-->id6((5)); - id3-->id7((10)); - id3-->id8((6)); - id4-->id9((4)); - id4-->id10(( )); - style id10 fill:#fff,stroke:#fff -``` - -:::: - -:::: column - -**But:** Transformer l'arbre en tas. - -* Indice $N/2-4 = 1$: `1`. -* `1 < 16 && 1 < 8`, `1 <=> max(1, 16, 8)` - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((16))-->id1((1)); - id0-->id2((8)); - id1-->id3((12)); - id1-->id4((7)); - id2-->id5((2)); - id2-->id6((5)); - id3-->id7((10)); - id3-->id8((6)); - id4-->id9((4)); - id4-->id10(( )); - style id10 fill:#fff,stroke:#fff -``` - -:::: - -::: - -``` - * * - | 16 | 1 | 8 | 12 | 7 | 2 | 5 | 10 | 6 | 4 | -``` - - -# Exemple de tri par tas (5/N) - -``` - | 16 | 1 | 8 | 12 | 7 | 2 | 5 | 10 | 6 | 4 | -``` - -::: columns - -:::: column - -**But:** Transformer l'arbre en tas. - -* Recommencer avec `1`. -* `1 <=> max(1, 12, 7)`. - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((16))-->id1((12)); - id0-->id2((8)); - id1-->id3((1)); - id1-->id4((7)); - id2-->id5((2)); - id2-->id6((5)); - id3-->id7((10)); - id3-->id8((6)); - id4-->id9((4)); - id4-->id10(( )); - style id10 fill:#fff,stroke:#fff -``` - -:::: - -:::: column - -**But:** Transformer l'arbre en tas. - -* Recommencer avec `1`. -* `1 <=> max(1, 10, 6)`. - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((16))-->id1((12)); - id0-->id2((8)); - id1-->id3((10)); - id1-->id4((7)); - id2-->id5((2)); - id2-->id6((5)); - id3-->id7((1)); - id3-->id8((6)); - id4-->id9((4)); - id4-->id10(( )); - style id10 fill:#fff,stroke:#fff -``` - -:::: - -::: - -``` - * * * - | 16 | 12 | 8 | 10 | 7 | 2 | 5 | 1 | 6 | 4 | -``` - -* L'arbre est un tas. - -# Exemple de tri par tas (6/N) - -``` - | 16 | 12 | 8 | 10 | 7 | 2 | 5 | 1 | 6 | 4 | -``` - -::: columns - -:::: column - -**But:** Trier les tas. - -* Échanger la racine, `16` (`max` de l'arbre) avec `4`. -* Traiter la racine. - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((4))-->id1((12)); - id0-->id2((8)); - id1-->id3((10)); - id1-->id4((7)); - id2-->id5((2)); - id2-->id6((5)); - id3-->id7((1)); - id3-->id8((6)); -``` - -:::: - -:::: column - -**But:** Trier les tas. - -* `4 <=> max(4, 12, 8)`. -* `4 <=> max(4, 10, 7)`. -* `4 <=> max(4, 1, 6)`. - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((12))-->id1((10)); - id0-->id2((8)); - id1-->id3((6)); - id1-->id4((7)); - id2-->id5((2)); - id2-->id6((5)); - id3-->id7((1)); - id3-->id8((4)); -``` - -:::: - -::: - -``` - | 12 | 10 | 8 | 6 | 7 | 2 | 5 | 1 | 4 || 16 -``` - - -# Exemple de tri par tas (7/N) - -``` - | 12 | 10 | 8 | 6 | 7 | 2 | 5 | 1 | 4 || 16 -``` - -::: columns - -:::: column - -**But:** Trier les tas. - -* Échanger la racine, `12` (`max` de l'arbre) avec `4`. -* Traiter la racine. - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((4))-->id1((10)); - id0-->id2((8)); - id1-->id3((6)); - id1-->id4((7)); - id2-->id5((2)); - id2-->id6((5)); - id3-->id7((1)); - id3-->id8(( )); - style id8 fill:#fff,stroke:#fff -``` - -:::: - -:::: column - -**But:** Trier les tas. - -* `4 <=> max(4, 10, 8)`. -* `4 <=> max(4, 6, 7)`. - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((10))-->id1((7)); - id0-->id2((8)); - id1-->id3((6)); - id1-->id4((4)); - id2-->id5((2)); - id2-->id6((5)); - id3-->id7((1)); - id3-->id8(( )); - style id8 fill:#fff,stroke:#fff -``` - -:::: - -::: - -``` - | 10 | 7 | 8 | 6 | 4 | 2 | 5 | 1 || 12 | 16 -``` - -# Exemple de tri par tas (8/N) - -``` - | 10 | 7 | 8 | 6 | 4 | 2 | 5 | 1 || 12 | 16 -``` - -::: columns - -:::: column - -**But:** Trier les tas. - -* Échanger la racine, `10` (`max` de l'arbre) avec `1`. -* Traiter la racine. - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((1))-->id1((7)); - id0-->id2((8)); - id1-->id3((6)); - id1-->id4((4)); - id2-->id5((2)); - id2-->id6((5)); -``` - -:::: - -:::: column - -**But:** Trier les tas. - -* `1 <=> max(1, 7, 8)`. -* `5 <=> max(1, 2, 5)`. - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((8))-->id1((7)); - id0-->id2((5)); - id1-->id3((6)); - id1-->id4((4)); - id2-->id5((2)); - id2-->id6((1)); -``` - -:::: - -::: - -``` - | 8 | 7 | 5 | 6 | 4 | 2 | 1 || 10 | 12 | 16 -``` - -# Exemple de tri par tas (9/N) - -``` - | 8 | 7 | 5 | 6 | 4 | 2 | 1 || 10 | 12 | 16 -``` - -::: columns - -:::: column - -**But:** Trier les tas. - -* Échanger la racine, `8` (`max` de l'arbre) avec `1`. -* Traiter la racine. - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((1))-->id1((7)); - id0-->id2((5)); - id1-->id3((6)); - id1-->id4((4)); - id2-->id5((2)); - id2-->id6(( )); - style id6 fill:#fff,stroke:#fff -``` - -:::: - -:::: column - -**But:** Trier les tas. - -* `1 <=> max(1, 7, 5)`. -* `1 <=> max(1, 6, 4)`. - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((7))-->id1((6)); - id0-->id2((5)); - id1-->id3((1)); - id1-->id4((4)); - id2-->id5((2)); - id2-->id6(( )); - style id6 fill:#fff,stroke:#fff -``` - -:::: - -::: - -``` - | 7 | 6 | 5 | 1 | 4 | 2 || 8 | 10 | 12 | 16 -``` - -# Exemple de tri par tas (10/N) - -``` - | 7 | 6 | 5 | 1 | 4 | 2 || 8 | 10 | 12 | 16 -``` - -::: columns - -:::: column - -**But:** Trier les tas. - -* Échanger la racine, `7` (`max` de l'arbre) avec `2`. -* Traiter la racine. - -```{.mermaid format=pdf width=150 loc=figs/} -graph TD; - id0((2))-->id1((6)); - id0-->id2((5)); - id1-->id3((1)); - id1-->id4((4)); -``` - -:::: - -:::: column - -**But:** Trier les tas. - -* `2 <=> max(2, 6, 5)`. -* `2 <=> max(2, 1, 4)`. - -```{.mermaid format=pdf width=150 loc=figs/} -graph TD; - id0((6))-->id1((4)); - id0-->id2((5)); - id1-->id3((1)); - id1-->id4((2)); -``` - -:::: - -::: - -``` - | 6 | 4 | 5 | 1 | 2 || 8 | 10 | 12 | 16 -``` - -# Exemple de tri par tas (11/N) - -``` - | 6 | 4 | 5 | 1 | 2 || 8 | 10 | 12 | 16 -``` - -::: columns - -:::: column - -**But:** Trier les tas. - -* Échanger la racine, `6` (`max` de l'arbre) avec `2`. -* Traiter la racine. - -```{.mermaid format=pdf width=150 loc=figs/} -graph TD; - id0((2))-->id1((4)); - id0-->id2((5)); - id1-->id3((1)); - id1-->id4(( )); - style id4 fill:#fff,stroke:#fff -``` - -:::: - -:::: column - -**But:** Trier les tas. - -* `2 <=> max(2, 4, 5)`. -* `2 <=> max(2, 1, 4)`. - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((5))-->id1((4)); - id0-->id2((2)); - id1-->id3((1)); - id1-->id4(( )); - style id4 fill:#fff,stroke:#fff -``` - -:::: - -::: - -``` - | 5 | 4 | 2 | 1 || 6 | 8 | 10 | 12 | 16 -``` - -# Exemple de tri par tas (12/N) - -``` - | 5 | 4 | 2 | 1 || 6 | 8 | 10 | 12 | 16 -``` - -::: columns - -:::: column - -**But:** Trier les tas. - -* Échanger la racine, `5` (`max` de l'arbre) avec `1`. -* Traiter la racine. - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((1))-->id1((4)); - id0-->id2((2)); -``` - -:::: - -:::: column - -**But:** Trier les tas. - -* `1 <=> max(1, 4, 2)`. - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((4))-->id1((1)); - id0-->id2((2)); -``` - -:::: - -::: - -``` - | 4 | 1 | 2 || 5 | 6 | 8 | 10 | 12 | 16 -``` - -# Exemple de tri par tas (13/N) - -``` - | 4 | 1 | 2 || 5 | 6 | 8 | 10 | 12 | 16 -``` - -::: columns - -:::: column - -**But:** Trier les tas. - -* Échanger la racine, `4` (`max` de l'arbre) avec `2`. -* Traiter la racine. - -```{.mermaid format=pdf width=400 loc=figs/} -graph TD; - id0((2))-->id1((1)); - id0-->id2(( )); - style id2 fill:#fff,stroke:#fff -``` - -:::: - -:::: column - -**But:** Trier les tas. Plus rien à trier - -* On fait les 2 dernières étapes en vitesse. -* Échange `2` avec `1`. -* Il reste que `1`. GGWP! - - -:::: - -::: - -``` - | 1 | 2 | 4 | 5 | 6 | 8 | 10 | 12 | 16 -``` - -# Exercice (10min) - -* Trier par tas le tableau - -``` - | 1 | 2 | 4 | 5 | 6 | 8 | 10 | 12 | 16 -``` - -* Mettez autant de détails que possible. -* Que constatez-vous? -* Postez le résultat sur matrix. - - - - diff --git a/slides/cours_18.md b/slides/cours_18.md new file mode 100644 index 0000000..0b223c0 --- /dev/null +++ b/slides/cours_18.md @@ -0,0 +1,1606 @@ +--- +title: "Arbres et tas" +date: "2024-03-19" +--- + +# Le pseudo-code de la suppression + +## Pour une feuille ou absent (ensemble) + +``` +arbre suppression(arbre, clé) + sous_arbre = position(arbre, clé) + si est_vide(sous_arbre) ou clé(sous_arbre) != clé + retourne vide + sinon + si est_feuille(sous_arbre) et clé(sous_arbre) == clé + nouvelle_feuille = parent(arbre, sous_arbre) + si est_vide(nouvelle_feuille) + arbre = vide + sinon + si gauche(nouvelle_feuille) == sous_arbre + gauche(nouvelle_feuille) = vide + sinon + droite(nouvelle_feuille) = vide + retourne sous_arbre +``` + +# Il nous manque le code pour le `parent` + +## Pseudo-code pour trouver le parent (5min -> matrix) + +. . . + +``` +arbre parent(arbre, sous_arbre) + si est_non_vide(arbre) + actuel = arbre + parent = actuel + clé = clé(sous_arbre) + faire + si (clé != clé(actuel)) + parent = actuel + si clé < clé(actuel) + actuel = gauche(actuel) + sinon + actuel = droite(actuel) + sinon + retour parent + tant_que (actuel != sous_arbre) + retourne vide +``` + +# Le pseudo-code de la suppression + +\footnotesize + +## Pour un seul enfant (5min -> matrix) + +. . . + +``` +arbre suppression(arbre, clé) + sous_arbre = position(arbre, clé) + si est_vide(gauche(sous_arbre)) ou est_vide(droite(sous_arbre)) + parent = parent(arbre, sous_arbre) + si est_vide(gauche(sous_arbre)) + si droite(parent) == sous_arbre + droite(parent) = droite(sous_arbre) + sinon + gauche(parent) = droite(sous_arbre) + sinon + si droite(parent) == sous_arbreou est_ + droite(parent) = gauche(sous_arbre) + sinon + gauche(parent) = gauche(sous_arbre) + retourne sous_arbre +``` + + +# Le pseudo-code de la suppression + +\footnotesize + +## Pour au moins deux enfants (ensemble) + +``` +arbre suppression(arbre, clé) + sous_arbre = position(arbre, clé) # on revérifie pas que c'est bien la clé + si est_non_vide(gauche(sous_arbre)) et est_non_vide(droite(sous_arbre)) + max_gauche = position(gauche(sous_arbre), clé) + échange(clé(max_gauche), clé(sous_arbre)) + suppression(gauche(sous_arbre), clé) +``` + +# Exercices (poster sur matrix) + +1. Écrire le pseudo-code de l'insertion purement en récursif. + +. . . + +``` +arbre insertion(arbre, clé) + si est_vide(arbre) + retourne nœud(clé) + + si (clé < arbre->clé) + gauche(arbre) = insert(gauche(arbre), clé) + sinon + droite(arbre) = insert(droite(arbre), clé) + retourne arbre +``` + +# Exercices (poster sur matrix) + +2. Écrire le pseudo-code de la recherche purement en récursif. + +. . . + +``` +bool recherche(arbre, clé) + si est_vide(arbre) + retourne faux // pas trouvée + si clé(arbre) == clé + retourne vrai // trouvée + si clé < clé(arbre) + retourne recherche(gauche(arbre), clé) + sinon + retourne recherche(droite(arbre), clé) +``` + +# Exercices (à la maison) + +3. Écrire une fonction qui insère des mots dans un arbre et ensuite affiche + l'arbre. + +# Trier un tableau à l'aide d'un arbre binaire + +* Tableau représenté comme un arbre binaire. +* Aide à comprendre "comment" trier, mais on ne construit jamais l'arbre. +* Complexité $O(N\log_2 N)$ en moyenne et grande stabilité (pas de cas + dégénérés). + +# Lien entre arbre et tableau + +* La racine de l'arbre set le premier élément du tableau. +* Les deux fils d'un nœud d'indice $i$, ont pour indices $2i+1$ et $2i+2$: + * Les fils du nœud $i=0$, sont à $2\cdot 0+1=1$ et $2\cdot 0+2=2$. + * Les fils du nœud $i=1$, sont à $2\cdot 1+1=3$ et $2\cdot 1+2=4$. + * Les fils du nœud $i=2$, sont à $2\cdot 2+2=5$ et $2\cdot 1+2=6$. + * Les fils du nœud $i=3$, sont à $2\cdot 3+1=7$ et $2\cdot 3+2=8$. +* Un élément d'indice $i$ a pour parent l'élément $(i-1)/2$ (division entière): + * Le parent du nœud $i=8$ est $(8-1)/2=3$. + * Le parent du nœud $i=7$ est $(7-1)/2=3$. + +# Visuellement + +::: columns + +:::: column + +* Où vont les indices correspondant du tableau? + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0(( ))-->id1(( )); + id0-->id2(( )); + id1-->id3(( )); + id1-->id4(( )); + id2-->id5(( )); + id2-->id6(( )); + id3-->id7(( )); + id3-->id8(( )); + id4-->id9(( )); + id4-->id10(( )); + style id10 fill:#fff,stroke:#fff +``` +:::: + +:::: column + +* Les flèche de gauche à droite, parent -> enfants. +* Les flèche de droite à gauche, enfants -> parent. + + + +:::: + +::: + +**Propriétés:** + +1. les feuilles sont toutes sur l'avant dernier ou dernier niveau. +2. les feuilles de profondeur maximale sont "tassée" à gauche. + +# Le tas (ou heap) + +## Définition + +* Un arbre est un tas, si la valeur de chacun de ses descendants est inférieure + ou égale à sa propre valeur. + +## Exemples (ou pas) + +``` +16 8 14 6 2 10 12 4 5 # Tas +16 14 8 6 2 10 12 4 5 # Non-tas, 10 > 8 et 12 > 8 +``` + +## Exercices (ou pas) + +``` +19 18 12 12 17 1 13 4 5 # Tas ou pas tas? +19 18 16 12 17 1 12 4 5 # Tas ou pas tas? +``` + +. . . + +``` +19 18 12 12 17 1 13 4 5 # Pas tas! 13 > 12 +19 18 16 12 17 1 12 4 5 # Tas! +``` + +# Exemple de tri par tas (1/13) + +``` + | 1 | 16 | 5 | 12 | 4 | 2 | 8 | 10 | 6 | 7 | +``` + +::: columns + +:::: column + +* Quel est l'arbre que cela représente? + +. . . + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((1))-->id1((16)); + id0-->id2((5)); + id1-->id3((12)); + id1-->id4((4)); + id2-->id5((2)); + id2-->id6((8)); + id3-->id7((10)); + id3-->id8((6)); + id4-->id9((7)); + id4-->id10(( )); + style id10 fill:#fff,stroke:#fff +``` + +:::: + +:::: column + +**But:** Transformer l'arbre en tas. + +* On commence à l'indice $N/2 = 5$: `4`. +* `7 > 4` (enfant `>` parent). +* intervertir `4` et `7`. + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((1))-->id1((16)); + id0-->id2((5)); + id1-->id3((12)); + id1-->id4((7)); + id2-->id5((2)); + id2-->id6((8)); + id3-->id7((10)); + id3-->id8((6)); + id4-->id9((4)); + id4-->id10(( )); + style id10 fill:#fff,stroke:#fff +``` + +:::: + +::: + +. . . + +``` + * * + | 1 | 16 | 5 | 12 | 7 | 2 | 8 | 10 | 6 | 4 | +``` + +# Exemple de tri par tas (2/13) + +``` + | 1 | 16 | 5 | 12 | 7 | 2 | 8 | 10 | 6 | 4 | +``` + +::: columns + +:::: column + +**But:** Transformer l'arbre en tas. + +* On continue à l'indice $N/2-1 = 4$: `12`. +* Déjà un tas, rien à faire. + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((1))-->id1((16)); + id0-->id2((5)); + id1-->id3((12)); + id1-->id4((7)); + id2-->id5((2)); + id2-->id6((8)); + id3-->id7((10)); + id3-->id8((6)); + id4-->id9((4)); + id4-->id10(( )); + style id10 fill:#fff,stroke:#fff +``` + +:::: + +:::: column + +**But:** Transformer l'arbre en tas. + +* On continue à l'indice $N/2-2 = 3$: `5`. +* `5 < 8`, échanger `8` et `5` (aka `max(2, 5, 8)`) + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((1))-->id1((16)); + id0-->id2((8)); + id1-->id3((12)); + id1-->id4((7)); + id2-->id5((2)); + id2-->id6((5)); + id3-->id7((10)); + id3-->id8((6)); + id4-->id9((4)); + id4-->id10(( )); + style id10 fill:#fff,stroke:#fff +``` + +:::: + +::: + +. . . + +``` + | 1 | 16 | 8 | 12 | 7 | 2 | 5 | 10 | 6 | 4 | +``` + +# Exemple de tri par tas (3/13) + +``` + | 1 | 16 | 5 | 12 | 7 | 2 | 8 | 10 | 6 | 4 | +``` + +::: columns + +:::: column + +**But:** Transformer l'arbre en tas. + +* Indice $N/2-1 = 4$: `12`. +* Déjà un tas, rien à faire. + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((1))-->id1((16)); + id0-->id2((5)); + id1-->id3((12)); + id1-->id4((7)); + id2-->id5((2)); + id2-->id6((8)); + id3-->id7((10)); + id3-->id8((6)); + id4-->id9((4)); + id4-->id10(( )); + style id10 fill:#fff,stroke:#fff +``` + +:::: + +:::: column + +**But:** Transformer l'arbre en tas. + +* Indice $N/2-2 = 3$: `5`. +* `5 < 8`, `5 <=> max(2, 5, 8)` + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((1))-->id1((16)); + id0-->id2((8)); + id1-->id3((12)); + id1-->id4((7)); + id2-->id5((2)); + id2-->id6((5)); + id3-->id7((10)); + id3-->id8((6)); + id4-->id9((4)); + id4-->id10(( )); + style id10 fill:#fff,stroke:#fff +``` + +:::: + +::: + +``` + * * + | 1 | 16 | 8 | 12 | 7 | 2 | 5 | 10 | 6 | 4 | +``` + +# Exemple de tri par tas (4/13) + +``` + | 1 | 16 | 8 | 12 | 7 | 2 | 5 | 10 | 6 | 4 | +``` + +::: columns + +:::: column + +**But:** Transformer l'arbre en tas. + +* Indice $N/2-3 = 1$: `16`. +* Déjà un tas, rien à faire. + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((1))-->id1((16)); + id0-->id2((8)); + id1-->id3((12)); + id1-->id4((7)); + id2-->id5((2)); + id2-->id6((5)); + id3-->id7((10)); + id3-->id8((6)); + id4-->id9((4)); + id4-->id10(( )); + style id10 fill:#fff,stroke:#fff +``` + +:::: + +:::: column + +**But:** Transformer l'arbre en tas. + +* Indice $N/2-4 = 1$: `1`. +* `1 < 16 && 1 < 8`, `1 <=> max(1, 16, 8)` + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((16))-->id1((1)); + id0-->id2((8)); + id1-->id3((12)); + id1-->id4((7)); + id2-->id5((2)); + id2-->id6((5)); + id3-->id7((10)); + id3-->id8((6)); + id4-->id9((4)); + id4-->id10(( )); + style id10 fill:#fff,stroke:#fff +``` + +:::: + +::: + +``` + * * + | 16 | 1 | 8 | 12 | 7 | 2 | 5 | 10 | 6 | 4 | +``` + + +# Exemple de tri par tas (5/13) + +``` + | 16 | 1 | 8 | 12 | 7 | 2 | 5 | 10 | 6 | 4 | +``` + +::: columns + +:::: column + +**But:** Transformer l'arbre en tas. + +* Recommencer avec `1`. +* `1 <=> max(1, 12, 7)`. + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((16))-->id1((12)); + id0-->id2((8)); + id1-->id3((1)); + id1-->id4((7)); + id2-->id5((2)); + id2-->id6((5)); + id3-->id7((10)); + id3-->id8((6)); + id4-->id9((4)); + id4-->id10(( )); + style id10 fill:#fff,stroke:#fff +``` + +:::: + +:::: column + +**But:** Transformer l'arbre en tas. + +* Recommencer avec `1`. +* `1 <=> max(1, 10, 6)`. + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((16))-->id1((12)); + id0-->id2((8)); + id1-->id3((10)); + id1-->id4((7)); + id2-->id5((2)); + id2-->id6((5)); + id3-->id7((1)); + id3-->id8((6)); + id4-->id9((4)); + id4-->id10(( )); + style id10 fill:#fff,stroke:#fff +``` + +:::: + +::: + +``` + * * * + | 16 | 12 | 8 | 10 | 7 | 2 | 5 | 1 | 6 | 4 | +``` + +* L'arbre est un tas. + +# Exemple de tri par tas (6/13) + +``` + | 16 | 12 | 8 | 10 | 7 | 2 | 5 | 1 | 6 | 4 | +``` + +::: columns + +:::: column + +**But:** Trier les tas. + +* Échanger la racine, `16` (`max` de l'arbre) avec `4`. +* Traiter la racine. + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((4))-->id1((12)); + id0-->id2((8)); + id1-->id3((10)); + id1-->id4((7)); + id2-->id5((2)); + id2-->id6((5)); + id3-->id7((1)); + id3-->id8((6)); +``` + +:::: + +:::: column + +**But:** Trier les tas. + +* `4 <=> max(4, 12, 8)`. +* `4 <=> max(4, 10, 7)`. +* `4 <=> max(4, 1, 6)`. + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((12))-->id1((10)); + id0-->id2((8)); + id1-->id3((6)); + id1-->id4((7)); + id2-->id5((2)); + id2-->id6((5)); + id3-->id7((1)); + id3-->id8((4)); +``` + +:::: + +::: + +``` + | 12 | 10 | 8 | 6 | 7 | 2 | 5 | 1 | 4 || 16 +``` + + +# Exemple de tri par tas (7/13) + +``` + | 12 | 10 | 8 | 6 | 7 | 2 | 5 | 1 | 4 || 16 +``` + +::: columns + +:::: column + +**But:** Trier les tas. + +* Échanger la racine, `12` (`max` de l'arbre) avec `4`. +* Traiter la racine. + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((4))-->id1((10)); + id0-->id2((8)); + id1-->id3((6)); + id1-->id4((7)); + id2-->id5((2)); + id2-->id6((5)); + id3-->id7((1)); + id3-->id8(( )); + style id8 fill:#fff,stroke:#fff +``` + +:::: + +:::: column + +**But:** Trier les tas. + +* `4 <=> max(4, 10, 8)`. +* `4 <=> max(4, 6, 7)`. + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((10))-->id1((7)); + id0-->id2((8)); + id1-->id3((6)); + id1-->id4((4)); + id2-->id5((2)); + id2-->id6((5)); + id3-->id7((1)); + id3-->id8(( )); + style id8 fill:#fff,stroke:#fff +``` + +:::: + +::: + +``` + | 10 | 7 | 8 | 6 | 4 | 2 | 5 | 1 || 12 | 16 +``` + +# Exemple de tri par tas (8/13) + +``` + | 10 | 7 | 8 | 6 | 4 | 2 | 5 | 1 || 12 | 16 +``` + +::: columns + +:::: column + +**But:** Trier les tas. + +* Échanger la racine, `10` (`max` de l'arbre) avec `1`. +* Traiter la racine. + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((1))-->id1((7)); + id0-->id2((8)); + id1-->id3((6)); + id1-->id4((4)); + id2-->id5((2)); + id2-->id6((5)); +``` + +:::: + +:::: column + +**But:** Trier les tas. + +* `1 <=> max(1, 7, 8)`. +* `5 <=> max(1, 2, 5)`. + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((8))-->id1((7)); + id0-->id2((5)); + id1-->id3((6)); + id1-->id4((4)); + id2-->id5((2)); + id2-->id6((1)); +``` + +:::: + +::: + +``` + | 8 | 7 | 5 | 6 | 4 | 2 | 1 || 10 | 12 | 16 +``` + +# Exemple de tri par tas (9/13) + +``` + | 8 | 7 | 5 | 6 | 4 | 2 | 1 || 10 | 12 | 16 +``` + +::: columns + +:::: column + +**But:** Trier les tas. + +* Échanger la racine, `8` (`max` de l'arbre) avec `1`. +* Traiter la racine. + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((1))-->id1((7)); + id0-->id2((5)); + id1-->id3((6)); + id1-->id4((4)); + id2-->id5((2)); + id2-->id6(( )); + style id6 fill:#fff,stroke:#fff +``` + +:::: + +:::: column + +**But:** Trier les tas. + +* `1 <=> max(1, 7, 5)`. +* `1 <=> max(1, 6, 4)`. + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((7))-->id1((6)); + id0-->id2((5)); + id1-->id3((1)); + id1-->id4((4)); + id2-->id5((2)); + id2-->id6(( )); + style id6 fill:#fff,stroke:#fff +``` + +:::: + +::: + +``` + | 7 | 6 | 5 | 1 | 4 | 2 || 8 | 10 | 12 | 16 +``` + +# Exemple de tri par tas (10/13) + +``` + | 7 | 6 | 5 | 1 | 4 | 2 || 8 | 10 | 12 | 16 +``` + +::: columns + +:::: column + +**But:** Trier les tas. + +* Échanger la racine, `7` (`max` de l'arbre) avec `2`. +* Traiter la racine. + +```{.mermaid format=pdf width=150 loc=figs/} +graph TD; + id0((2))-->id1((6)); + id0-->id2((5)); + id1-->id3((1)); + id1-->id4((4)); +``` + +:::: + +:::: column + +**But:** Trier les tas. + +* `2 <=> max(2, 6, 5)`. +* `2 <=> max(2, 1, 4)`. + +```{.mermaid format=pdf width=150 loc=figs/} +graph TD; + id0((6))-->id1((4)); + id0-->id2((5)); + id1-->id3((1)); + id1-->id4((2)); +``` + +:::: + +::: + +``` + | 6 | 4 | 5 | 1 | 2 || 8 | 10 | 12 | 16 +``` + +# Exemple de tri par tas (11/13) + +``` + | 6 | 4 | 5 | 1 | 2 || 8 | 10 | 12 | 16 +``` + +::: columns + +:::: column + +**But:** Trier les tas. + +* Échanger la racine, `6` (`max` de l'arbre) avec `2`. +* Traiter la racine. + +```{.mermaid format=pdf width=150 loc=figs/} +graph TD; + id0((2))-->id1((4)); + id0-->id2((5)); + id1-->id3((1)); + id1-->id4(( )); + style id4 fill:#fff,stroke:#fff +``` + +:::: + +:::: column + +**But:** Trier les tas. + +* `2 <=> max(2, 4, 5)`. +* `2 <=> max(2, 1, 4)`. + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((5))-->id1((4)); + id0-->id2((2)); + id1-->id3((1)); + id1-->id4(( )); + style id4 fill:#fff,stroke:#fff +``` + +:::: + +::: + +``` + | 5 | 4 | 2 | 1 || 6 | 8 | 10 | 12 | 16 +``` + +# Exemple de tri par tas (12/13) + +``` + | 5 | 4 | 2 | 1 || 6 | 8 | 10 | 12 | 16 +``` + +::: columns + +:::: column + +**But:** Trier les tas. + +* Échanger la racine, `5` (`max` de l'arbre) avec `1`. +* Traiter la racine. + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((1))-->id1((4)); + id0-->id2((2)); +``` + +:::: + +:::: column + +**But:** Trier les tas. + +* `1 <=> max(1, 4, 2)`. + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((4))-->id1((1)); + id0-->id2((2)); +``` + +:::: + +::: + +``` + | 4 | 1 | 2 || 5 | 6 | 8 | 10 | 12 | 16 +``` + +# Exemple de tri par tas (13/13) + +``` + | 4 | 1 | 2 || 5 | 6 | 8 | 10 | 12 | 16 +``` + +::: columns + +:::: column + +**But:** Trier les tas. + +* Échanger la racine, `4` (`max` de l'arbre) avec `2`. +* Traiter la racine. + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((2))-->id1((1)); + id0-->id2(( )); + style id2 fill:#fff,stroke:#fff +``` + +:::: + +:::: column + +**But:** Trier les tas. Plus rien à trier + +* On fait les 2 dernières étapes en vitesse. +* Échange `2` avec `1`. +* Il reste que `1`. GGWP! + + +:::: + +::: + +``` + | 1 | 2 | 4 | 5 | 6 | 8 | 10 | 12 | 16 +``` + +# Exercice (10min) + +* Trier par tas le tableau + +``` + | 1 | 2 | 4 | 5 | 6 | 8 | 10 | 12 | 16 +``` + +* Mettez autant de détails que possible. +* Que constatez-vous? +* Postez le résultat sur matrix. + +# L'algorithme du tri par tas (1/2) + +\footnotesize + +## Deux étapes + +1. Entassement: transformer l'arbre en tas. +2. Échanger la racine avec le dernier élément et entasser la racine. + +## Pseudo-code d'entassement de l'arbre (15 min, matrix) + +. . . + +```python +rien tri_par_tas(tab) + entassement(tab) + échanger(tab[0], tab[size(tab)-1]) + pour i de size(tab)-1 à 2 + tamisage(tab, 0) + échanger(tab[0], tab[i-1]) + +rien entassement(tab) + pour i de size(tab)/2-1 à 0 + tamisage(tab, i) + +rien tamisage(tab, i) + ind_max = ind_max(tab, i, gauche(i), droite(i)) + si i != ind_max + échanger(tab[i], tab[ind_max]) + tamisage(tab, ind_max) +``` + +# L'algorithme du tri par tas (2/2) + +* Fonctions utilitaires + + ```python + entier ind_max(tab, i, g, d) + ind_max = i + si tab[ind_max] < tab[g] && size(tab) > g + ind_max = g + si tab[ind_mx] < tab[d] && size(tab) > d + ind_max = d + retourne ind_max + + entier gauche(i) + retourne 2 * i + 1 + + entier droite(i) + retourne 2 * i + 2 + ``` + + +<!-- # L'algorithme du tri par tas (3/4) + +\footnotesize + +## Implémenter en C l'algorithme du tri par tas (matrix, 20min) + +. . . + +```C +void heapsort(int size, int tab[size]) { + heapify(size, tab); + swap(tab, tab + size - 1); + for (int s = size - 1; s > 1; s--) { + sift_up(s, tab, 0); + swap(tab, tab + s - 1); + } +} +void heapify(int size, int tab[size]) { + for (int i = size / 2 - 1; i >= 0; i--) { + sift_up(size, tab, i); + } +} +void sift_up(int size, int tab[size], int i) { + int ind_max = ind_max3(size, tab, i, left(i), right(i)); + if (i != ind_max) { + swap(tab + i, tab + ind_max); + sift_up(size, tab, ind_max); + } +} +``` + +# L'algorithme du tri par tas (4/4) + +\footnotesize + +## Fonctions utilitaires + +. . . + +```C +int ind_max3(int size, int tab[size], int i, int l, int r) { + int ind_max = i; + if (l < size && tab[ind_max] < tab[l]) { + ind_max = l; + } + if (r < size && tab[ind_max] < tab[r]) { + ind_max = r; + } + return ind_max; +} +void swap(int *a, int *b) { + int tmp = *a; + *a = *b; + *b = tmp; +} +int left(int i) { + return 2 * i + 1; +} +int right(int i) { + return 2 * i + 2; +} +``` --> + + +# Complexités + +::: columns + +:::: column + +## Complexité de la recherche + +1. En moyenne? +2. Dans le pire des cas? + +. . . + +1. $O(\log_2(N))$ +2. $O(N)$ + +:::: + +:::: column + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((10))-->id1((9)); + id0-->id8(( )); + id1-->id2((7)); + id1-->id9(( )); + id2-->id3((6)); + id2-->id10(( )); + id3-->id4((5)); + id3-->id11(( )); + style id8 fill:#fff,stroke:#fff + style id9 fill:#fff,stroke:#fff + style id10 fill:#fff,stroke:#fff + style id11 fill:#fff,stroke:#fff +``` + +:::: + +::: + +# Un meilleur arbre + +* Quelle propriété doit satisfaire un arbre pour être $O(\log_2(N))$? + +. . . + +* Si on a environ le même nombre de nœuds dans les sous-arbres. + +## Définition + +Un arbre binaire est parfaitement équilibré si, pour chaque +nœud, la différence entre les nombres de nœuds des sous- +arbres gauche et droit vaut au plus 1. + +* Si l'arbre est **parfaitement équilibré**, alors tout ira bien. +* Quelle est la hauteur (profondeur) d'un arbre parfaitement équilibré? + +. . . + +* $O(\log_2(N))$. + + +# Équilibre parfait ou pas? + +::: columns + +:::: column + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((W))-->id1((B)); + id0-->id8((Y)); + id1-->id2((A)); + id1-->id9(( )); + id8-->id10((X)); + id8-->id11(( )); + style id9 fill:#fff,stroke:#fff + style id11 fill:#fff,stroke:#fff +``` + +:::: + +:::: column + +. . . + +``` +É +Q +U +I +L +I +B +R +É +``` + +:::: + +::: + +# Équilibre parfait ou pas? + +::: columns + +:::: column + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((16))-->id1((10)); + id0-->id2((19)); + id1-->id3((8)); + id1-->id4((12)); + id4-->id5((11)); + id4-->id6(( )); + id2-->id7((17)); + id2-->id8(( )); + id7-->id9(( )); + id7-->id10((18)); + style id6 fill:#fff,stroke:#fff + style id8 fill:#fff,stroke:#fff + style id9 fill:#fff,stroke:#fff +``` + +:::: + +:::: column + +. . . + +``` +P +A +S + +É +Q +U +I +L +I +B +R +É +``` + +:::: + +::: + +# Arbres AVL + +\footnotesize + +* Quand est-ce qu'on équilibre un arbre? + +. . . + +* A l'insertion/suppression. +* Maintenir un arbre en état d'équilibre parfait: cher (insertion, suppression). +* On peut "relaxer" la condition d'équilibre: profondeur (hauteur) au lieu du + nombre de nœuds: + * La hauteur $\sim\log_2(N)$. + +## Définition + +Un arbre AVL (Adelson-Velskii et Landis) est un arbre binaire de recherche dans +lequel, pour chaque nœud, la différence de hauteur entre le sous-arbre gauche et droit vaut au plus 1. + +* Relation entre nœuds et hauteur: +$$ +\log_2(1+N)\leq 1+H\leq 1.44\cdot\log_2(2+N),\quad N=10^5,\ 17\leq H \leq 25. +$$ +* Permet l'équilibrage en temps constant: insertion/suppression $O(\log_2(N))$. + +# Notation + +* `hg`: hauteur du sous-arbre gauche. +* `hd`: hauteur du sous-arbre droit. +* `facteur d'équilibre = fe = hd - hg` +* Que vaut `fe` si l'arbre est AVL? + +. . . + +* `fe = {-1, 0, 1}` + + +# AVL ou pas? + +::: columns + +:::: column + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((12))-->id1((10)); + id0-->id2((19)); + id2-->id3((17)); + id2-->id4((97)); +``` + +:::: + +:::: column + +. . . + +``` +A +V +L +``` + +:::: + +::: + +# AVL ou pas? + +::: columns + +:::: column + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((12))-->id1((1)); + id0-->id2((19)); + id2-->id3((17)); + id2-->id4((97)); + id4-->id5((37)); + id4-->id6(( )); + style id6 fill:#fff,stroke:#fff +``` + +:::: + +:::: column + +. . . + +``` +P +A +S + +A +V +L +``` + +:::: + +::: + +# Insertion dans un arbre AVL (1/N) + +1. On part d'un arbre AVL. +2. On insère un nouvel élément. + +::: columns + +:::: column + +* `hd ? hg`. +* Insertion de `4`? + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((12))-->id1((1)); + id0-->id2((19)); +``` + +:::: + +:::: column + +. . . + +* `hd = hg` + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((12))-->id1((1)); + id0-->id2((19)); + id1-->id4(( )); + id1-->id5((4)); + style id4 fill:#fff,stroke:#fff +``` + +* `fe = -1` + +:::: + +::: + +# Insertion dans un arbre AVL (2/N) + +1. On part d'un arbre AVL. +2. On insère un nouvel élément. + +::: columns + +:::: column + +* `hd ? hg`. +* Insertion de `4`? + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((12))-->id1((1)); + id0-->id2((19)); + id2-->id3((18)); + id2-->id4(( )); + style id4 fill:#fff,stroke:#fff +``` + +:::: + +:::: column + +. . . + +* `hd < hg` + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((12))-->id1((1)); + id0-->id2((19)); + id2-->id3((18)); + id2-->id4(( )); + id1-->id5(( )); + id1-->id6((4)); + style id4 fill:#fff,stroke:#fff + style id5 fill:#fff,stroke:#fff +``` + +* `fe = 0` + +:::: + +::: + +# Insertion dans un arbre AVL (3/N) + +\footnotesize + +1. On part d'un arbre AVL. +2. On insère un nouvel élément. + +::: columns + +:::: column + +* `hd ? hg`. +* Insertion de `4`? + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((12))-->id1((1)); + id0-->id2((19)); + id1-->id3(( )); + id1-->id4((6)); + id2-->id5(( )); + id2-->id6(( )); + style id3 fill:#fff,stroke:#fff + style id5 fill:#fff,stroke:#fff + style id6 fill:#fff,stroke:#fff +``` + +:::: + +:::: column + +. . . + +* `hd < hg` + +```{.mermaid format=pdf width=400 loc=figs/} +graph TD; + id0((12))-->id1((1)); + id0-->id2((19)); + id1-->id3(( )); + id1-->id4((6)); + id4-->id5((4)); + id4-->id6(( )); + id2-->id7(( )); + id2-->id8(( )); + style id3 fill:#fff,stroke:#fff + style id6 fill:#fff,stroke:#fff + style id7 fill:#fff,stroke:#fff + style id8 fill:#fff,stroke:#fff +``` + +:::: + +::: + +**Déséquilibre!** Que vaut `fe`? + +. . . + +* `fe = 2` + +# Les cas de déséquilibre + + +::: columns + +:::: column + +## Cas 1a + +* `u`, `v`, `w` même hauteur. +* déséquilibre en `B` après insertion dans `u` + + + +:::: + +:::: column + +## Cas 1a + +* Comment rééquilibrer? + +. . . + +* ramène `u`, `v` `w` à la même hauteur. +* `v` à droite de `A` (gauche de `B`) + + + +:::: + +::: + +# Les cas de déséquilibre + + +::: columns + +:::: column + +## Cas 1b (symétrique 1a) + + + +:::: + +:::: column + +## Cas 1b (symétrique 1a) + +* Comment rééquilibrer? + +. . . + + + +:::: + +::: + +# Les cas de déséquilibre + + +::: columns + +:::: column + +## Cas 2a + +* `h(v1)=h(v2), h(u)=h(w)`. +* déséquilibre en `C` après insertion dans `v2` + + + +:::: + +:::: column + +## Cas 2a + +* Comment rééquilibrer? + +. . . + +* ramène `u`, `v2`, `w` à la même hauteur (`v1` pas tout à fait). +* `v2` à droite de `B` (gauche de `C`) +* `B` à droite de `A` (gauche de `C`) +* `v1` à droite de `A` (gauche de `B`) + + + +:::: + +::: + + +# Les cas de déséquilibre + + +::: columns + +:::: column + +## Cas 2b (symétrique 2a) + + + +:::: + +:::: column + +## Cas 2b (symétrique 2a) + +* Comment rééquilibrer? + +. . . + + + +:::: + +::: + + +[^2]: Copyright cours de mathématiques pendant trop d'années. + -- GitLab