From 2dd779cb6973524efe9fd54fd2bbd62b809ec329 Mon Sep 17 00:00:00 2001
From: Orestis <orestis.malaspinas@pm.me>
Date: Thu, 18 May 2023 19:14:02 +0200
Subject: [PATCH] added new content

---
 slides/cours_22.md | 469 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 469 insertions(+)
 create mode 100644 slides/cours_22.md

diff --git a/slides/cours_22.md b/slides/cours_22.md
new file mode 100644
index 0000000..d2dfe6f
--- /dev/null
+++ b/slides/cours_22.md
@@ -0,0 +1,469 @@
+---
+title: "B-arbres"
+date: "2023-05-19"
+---
+
+# Rappel: Les B-arbres
+
+## Pourquoi utiliser un B-arbre?
+
+. . .
+
+## À quoi ressemble un B-arbre?
+
+. . .
+
+## Qu'est-ce qu'un B-arbre d'ordre $n$
+
+* Chaque page d'un arbre contient au plus $2\cdot n$ *clés*;
+* Chaque page (excepté la racine) contient au moins $n$ clés;
+* Chaque page qui contient $m$ clés contient soit:
+    * $0$ descendants;
+    * $m+1$ descendants.
+* Toutes les pages terminales apparaissent au même niveau.
+
+
+# Rappel: Les B-arbres
+
+## Quelques propriétés
+
+* Dans chaque nœud les clés sont **triées**.
+* Chaque page contient au plus $n$ nœuds: check;
+* Chaque nœud avec $m$ clés a $m+1$ descendants;
+* Toutes les feuilles apparaissent au même niveau.
+
+# Les B-arbres
+
+## Structure de données
+
+* Chaque page a une contrainte de remplissage, par rapport à l'ordre de l'arbre;
+* Un nœud (page) est composé d'un tableau de clés/pointeurs vers les enfants;
+
+```
+P_0 | K_1 | P_1 | K_2 |  | P_i | K_{i+1} |  | P_{m-1} | K_m | P_m
+```
+
+* `P_0`, ..., `P_m` pointeurs vers enfants;
+* `K_1`, ..., `K_m` les clés.
+* Il y a `m+1` pointeurs mais `m` clés.
+* Comment faire pour gérer l'insertion?
+
+# Les B-arbres
+
+## Faire un dessin de la structure de données (3min matrix)?
+
+. . .
+
+![Structure d'une page de B-arbre d'ordre 2.](figs/barbres_struct.png)
+
+1. On veut un tableau de `P_i, K_i => struct`;
+2. `K_0` va être en "trop";
+3. Pour simplifier l'insertion dans une page, on ajoute un élément de plus.
+
+# Les B-arbres
+
+## L'insertion cas nœud pas plein, insertion `4`?
+
+![](figs/barbres_insert_easy.svg){width=50%}
+
+. . .
+
+## Solution
+
+![](figs/barbres_insert_easy_after.svg){width=50%}
+
+# Les B-arbres
+
+## L'insertion cas nœud pas plein, insertion `N`
+
+* On décale les éléments plus grand que `N`;
+* On insère `N` dans la place "vide";
+* Si la page n'est pas pleine, on a terminé.
+
+# Les B-arbres
+
+## L'insertion cas nœud plein, insertion `2`?
+
+![](figs/barbres_insert_hard_before.svg){width=50%}
+
+. . .
+
+## Solution
+
+![](figs/barbres_insert_hard_during.svg){width=50%}
+
+# Les B-arbres
+
+## L'insertion cas nœud plein, promotion `3`?
+
+![](figs/barbres_insert_hard_during.svg){width=50%}
+
+. . .
+
+## Solution
+
+![](figs/barbres_insert_hard_after.svg)
+
+# Les B-arbres
+
+## L'insertion cas nœud plein, insertion `N`
+
+* On décale les éléments plus grand que `N`;
+* On insère `N` dans la place "vide";
+* Si la page est pleine:
+    * On trouve la valeur médiane `M` de la page (quel indice?);
+    * On crée une nouvelle page de droite;
+    * On copie les valeur à droite de `M` dans la nouvelle page;
+    * On promeut `M` dans la page du dessus;
+    * On connecte le pointeur de gauche de `M` et de droite de `M` avec l'ancienne et la nouvelle page respectivement.
+
+# Les B-arbres
+
+## Pseudo-code structure de données (3min, matrix)?
+
+. . .
+
+```C
+struct page
+    entier ordre, nb
+    element tab[2*ordre + 2]
+```
+
+```C
+struct element
+    int clé
+    page pg
+```
+
+# Les B-arbres
+
+\footnotesize
+
+## Les fonctions utilitaires (5min matrix)
+
+```C
+booléen est_feuille(page)     // la page est elle une feuille?
+entier position(page, valeur) // à quelle indice on insère?
+booléen est_dans_page(page, valeur) // la valeur est dans la page
+```
+
+. . .
+
+```C
+booléen est_feuille(page) 
+    retourne (page.tab[0].pg == vide)
+
+entier position(page, valeur)
+    i = 0
+    tant que i < page.nb && val >= page.tab[i+1].clef
+        i += 1
+    retourne i
+
+booléen est_dans_page(page, valeur)
+    i = position(page, valeur)
+    retourne (page.nb > 0 && page.tab[i].val == valeur)
+```
+
+# Les B-arbres
+
+\footnotesize
+
+## Les fonctions utilitaires (5min matrix)
+
+```C
+page nouvelle_page(ordre)  // creer une page
+rien liberer_memoire(page) // liberer tout un arbre!
+```
+. . .
+
+```C
+page nouvelle_page(ordre)
+    page = allouer(page)
+    page.ordre = ordre
+    page.nb = 0
+    page.tab = allouer(2*ordre+2)
+    retourner page
+
+rien liberer_memoire(page)
+    si est_feuille(page)
+        liberer(page.tab)
+        liberer(page)
+    sinon
+        pour fille dans page.tab
+            liberer_memoire(fille)
+        liberer(page.tab)
+        liberer(page)
+```
+
+# Les B-arbres
+
+## Les fonctions (5min matrix)
+
+```C
+page recherche(page, valeur) // retourner la page contenant
+                             // la valeur ou vide 
+```
+
+. . .
+
+```C
+page recherche(page, valeur)
+    si est_dans_page(page, valeur)
+        retourne page
+    sinon si est_feuille(page) 
+        retourne vide
+    sinon
+        recherche(page.tab[position(page, valeur)], valeur)
+```
+
+# Les B-arbres
+
+## Les fonctions
+
+```C
+page inserer_valeur(page, valeur) // inserer une valeur
+```
+
+. . .
+
+```C
+page inserer_valeur(page, valeur)
+    element = nouvel_element(valeur)
+    // on change element pour savoir s'il faut le remonter
+    inserer_element(page, element) 
+    si element.page != vide && page.nb > 2*page.ordre
+        // si on atteint le sommet!
+        page = ajouter_niveau(page, element) 
+    retourne page
+```
+
+# Les B-arbres
+
+## Les fonctions
+
+```C
+rien inserer_element(page, element) // inserer un element et voir s'il remonte
+```
+
+. . .
+
+```C
+rien inserer_element(page, element)
+    si est_feuille(page)
+        placer(page, element)
+    sinon
+        sous_page = page.tab[position(page, element)].page
+        inserer_element(sous_page, element)
+        // un element a été promu
+        si element.page != vide
+            placer(page, element)
+```
+
+# Les B-arbres
+
+## Les fonctions (5min matrix)
+
+```C
+rien placer(page, element) // inserer un élément
+```
+
+. . .
+
+```C
+rien placer(page, element)
+    pos = position(page, element.clé)
+    pour i de 2*page.ordre à pos+1
+        page.tab[i+1] = page.tab[i]
+    page.tab[pos+1] = element
+    page.nb += 1
+    si page.nb > 2*page.ordre
+        scinder(page, element)
+```
+
+# Les B-arbres
+
+## Les fonctions (5min matrix)
+
+```C
+rien scinder(page, element) // casser une page et remonter
+```
+
+. . .
+
+```C
+rien scinder(page, element)
+    new_page = new_page(page.ordre)
+    new_page.nb = page.ordre
+    pour i de 0 à ordre inclu
+        new_page.tab[i] = page.tab[i+ordre+1]
+    element.clé = page.tab[ordre+1].clé
+    element.page = new_page
+```
+
+# Les B-arbres
+
+## Les fonctions (5min matrix)
+
+```C
+page ajouter_niveau(page, element) // si on remonte à la racine...
+                                   // on doit créer une nouvelle racine
+```
+
+. . .
+
+```C
+page ajouter_niveau(page, element) 
+    tmp = nouvelle_page(page.ordre)
+    tmp.tab[0].page = page
+    tmp.tab[1].clé = element.clé
+    tmp.tab[1].page = element.page
+    retourne tmp
+```
+
+# Les B-arbres: suppression
+
+## Cas simplissime
+
+![Suppression de 25.](figs/barbres_ordre2_supp1.svg){width=80%}
+
+. . .
+
+![25 supprimé, on décale juste 27.](figs/barbres_ordre2_supp2.svg){width=80%}
+
+# Les B-arbres: suppression
+
+## Cas simple
+
+
+![Suppression de 27.](figs/barbres_ordre2_supp2.svg){width=60%}
+
+. . .
+
+* On retire 27, mais....
+    * Chaque page doit avoir au moins 2 éléments.
+    * On doit déplacer des éléments dans une autre feuille! Mais comment?
+
+. . .
+
+![La médiane de la racine descend, fusion de 20 à gauche, et suppression à droite.](figs/barbres_ordre2_supp3.svg){width=60%}
+
+# Les B-arbres: suppression
+
+## Cas moins simple
+
+![Suppression de 5.](figs/barbres_ordre2_supp4.svg){width=60%}
+
+. . .
+
+* Un élément à droite, comment on fait?
+    * Remonter `7`, serait ok si racine, mais... c'est pas forcément.
+    * On redistribue les feuilles.
+
+. . .
+
+![Descente de `3`, remontée médiane des feuilles `2`, .](figs/barbres_ordre2_supp5.svg){width=60%}
+
+# Les B-arbres: suppression
+
+## Cas ultra moins simple
+
+![Suppression de 3.](figs/barbres_ordre2_supp6.svg){width=60%}
+
+. . .
+
+* `7` seul:
+    * Fusionner les feuilles et redistribuer, comment?
+
+. . .
+
+![Descendre `-1`, déplacer `7` à gauche, et décaler les éléments de droite au milieu.](figs/barbres_ordre2_supp7.svg){width=60%}
+
+# Les B-arbres: suppression
+
+## Cas ultra moins simple
+
+![On a pas fini...](figs/barbres_ordre2_supp7.svg){width=60%}
+
+. . .
+
+* `8` est seul, c'est plus un B-arbre :
+    * Fusionner le niveau 2 et redistribuer, comment?
+
+. . .
+
+![Fusionner `8`, `17`, `22` et descendre `12`.](figs/barbres_ordre2_supp8.svg){width=40%}
+
+. . .
+
+* La profondeur a diminué de 1.
+
+# Les B-arbres: suppression
+
+## Algorithme pour les feuilles!
+
+* Si la clé est supprimée d'une feuille:
+    * Si on a toujours `n` (ordre de l'arbre) clés dans la feuille on décale simplement les clés.
+    * Sinon on combine (récursivement) avec le noeud voisin et on descend la clé médiane.
+
+# Les B-arbres: suppression
+
+## Cas non-feuille!
+
+![Suppression de 8.](figs/barbres_ordre2_supp9.svg){width=60%}
+
+. . .
+
+* On sait comment effacer une valeur d'une feuille, donc?
+
+. . .
+
+![Échanger le `8` avec le plus grand du sous-arbre de gauche.](figs/barbres_ordre2_supp10.svg){width=60%}
+
+* Ensuite?
+
+# Les B-arbres: suppression
+
+## Cas non-feuille!
+
+![Suppression de 8.](figs/barbres_ordre2_supp10.svg){width=60%}
+
+. . .
+
+* On sait comment effacer une valeur d'une feuille!
+
+. . .
+
+![Yaka enlever le 8 de la feuille comme avant!](figs/barbres_ordre2_supp11.svg){width=60%}
+
+# Les B-arbres: suppression
+
+## Algorithme pour les non-feuilles!
+
+* Si la clé est supprimée d'une page qui n'est pas une feuille:
+    * On échange la valeur avec la valeur de droite de la page de gauche
+    * On supprime comme pour une feuille!
+
+## Et maintenant des exos par millions!
+
+
+
+<!-- # Les B-arbres -->
+
+<!-- ## Structure de données en C (3min, matrix) -->
+
+<!-- . . . -->
+
+<!-- ```C -->
+<!-- typedef struct _page { -->
+<!--     int order, nb; -->
+<!--     struct _element *tab; -->
+<!-- } page; -->
+<!-- ``` -->
+
+<!-- ```C -->
+<!-- typedef struct element { -->
+<!--     int key; -->
+<!--     struct _page *pg; -->
+<!-- } element; -->
+<!-- ``` -->
+
-- 
GitLab