Skip to content
Snippets Groups Projects
Verified Commit bd48cb08 authored by orestis.malaspin's avatar orestis.malaspin
Browse files

ajout cours 18

parent 39aa094c
No related branches found
No related tags found
No related merge requests found
---
title: "Arbres AVL"
date: "2023-03-31"
---
# Questions sur les notions du dernier cours
* Qu'est-ce qu'un arbre AVL?
. . .
* Un arbre binaire qui a la propriété suivante:
* La différence de hauteur de chaque noeud est d'au plus 1.
* Tous les noeuds ont `fe = hd - hg = {-1, 0, 1}`.
* Pourquoi utiliser un arbre AVL plutôt qu'un arbre binaire de recherche?
. . .
* Insertion/recherche/... toujours en $O(\log_2(N))$.
# AVL ou pas?
```{.mermaid format=pdf width=400 loc=figs/}
graph TD;
id0((21))-->id1((9));
id0-->id2((40));
id1-->id3((5));
id1-->id4((10));
id3-->id5((3));
id3-->id6((7))
id6-->id7((6))
id6-->id8(( ))
id2-->id9((33))
id2-->id10((61))
id9-->id11((22))
id9-->id12((39))
id10-->id13(( ))
id10-->id14((81))
style id8 fill:#fff,stroke:#fff
style id13 fill:#fff,stroke:#fff
```
. . .
* Ajouter un noeud pour qu'il le soit plus.
# Insertion dans un arbre AVL
\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`
![Après insertion](figs/cas1a_gauche.png)
::::
:::: column
## Cas 1a
* Comment rééquilibrer?
. . .
* ramène `u`, `v` `w` à la même hauteur.
* `v` à droite de `A` (gauche de `B`)
![Après équilibrage](figs/cas1a_droite.png)
::::
:::
# Les cas de déséquilibre
::: columns
:::: column
## Cas 1b (symétrique 1a)
![Après insertion](figs/cas1b_gauche.png)
::::
:::: column
## Cas 1b (symétrique 1a)
* Comment rééquilibrer?
. . .
![Après équilibrage](figs/cas1b_droite.png)
::::
:::
# 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`
![Après insertion](figs/cas2a_gauche.png)
::::
:::: 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`)
![Après équilibrage](figs/cas2a_droite.png)
::::
:::
# Les cas de déséquilibre
::: columns
:::: column
## Cas 2b (symétrique 2a)
![Après insertion](figs/cas2b_gauche.png)
::::
:::: column
## Cas 2b (symétrique 2a)
* Comment rééquilibrer?
. . .
![Après équilibrage](figs/cas2b_droite.png)
::::
:::
# Le facteur d'équilibre (balance factor)
## Définition
```
fe(arbre) = hauteur(droite(arbre)) - hauteur(gauche(arbre))
```
## Valeurs possibles?
. . .
```
fe = {-1, 0, 1} // arbre AVL
fe = {-2, 2} // arbre déséquilibré
```
![Illustration du `fe`](figs/facteur_equilibre.png){width=40%}
# Algorithme d'insertion
* Insérer le noeud comme d'habitude.
* Mettre à jour les facteurs d'équilibre jusqu'à la racine (ou au premier
noeud déséquilibré).
* Rééquilibrer le noeud si nécessaire.
## Cas possibles
::: columns
:::: column
## Sous-arbre gauche (avant)
```
fe(P) = 1
fe(P) = 0
fe(P) = -1
```
::::
:::: column
## Sous-arbre gauche (après)
. . .
```
=> fe(P) = 0
=> fe(P) = -1
=> fe(P) = -2 // Rééquilibrer P
```
::::
:::
# Algorithme d'insertion
* Insérer le noeud comme d'habitude.
* Mettre à jour les facteurs d'équilibre jusqu'à la racine (ou au premier
noeud déséquilibré).
* Rééquilibrer le noeud si nécessaire.
## Cas possibles
::: columns
:::: column
## Sous-arbre droit (avant)
```
fe(P) = 1
fe(P) = 0
fe(P) = -1
```
::::
:::: column
## Sous-arbre droit (après)
. . .
```
=> fe(P) = 0
=> fe(P) = +1
=> fe(P) = +2 // Rééquilibrer P
```
::::
:::
# Rééquilibrage
## Lien avec les cas vus plus tôt
```
fe(P) = -2 && fe(gauche(P)) = -1 => cas 1a
fe(P) = -2 && fe(gauche(P)) = +1 => cas 2a
fe(P) = +2 && fe(droite(P)) = -1 => cas 2b
fe(P) = +2 && fe(droite(P)) = +1 => cas 1b
```
## Dessiner les différents cas, sur le dessin ci-dessous
![On verra un peu après les rotations.](figs/rotation_gauche_droite.png)
# La rotation
## La rotation gauche (5min, matrix)
![L'arbre de droite devient celui de gauche. Comment?](figs/rotation_gauche_droite.png)
. . .
\footnotesize
```
arbre rotation_gauche(arbre P)
si est_non_vide(P)
Q = droite(P)
droite(P) = gauche(Q)
gauche(Q) = P
retourne Q
retourne P
```
# La rotation en C (1/2)
## La rotation gauche
```
arbre rotation_gauche(arbre P)
si est_non_vide(P)
Q = droite(P)
droite(P) = gauche(Q)
gauche(Q) = P
retourne Q
retourne P
```
## Écrire le code C correspondant (5min, matrix)
1. Structure de données
2. Fonction `tree_t rotation_left(tree_t tree)`
. . .
\footnotesize
```C
typedef struct _node {
int key;
struct _node *left, *right;
int bf; // balance factor
} node;
typedef node *tree_t;
```
# La rotation en C (2/2)
\footnotesize
```C
tree_t rotation_left(tree_t tree) {
tree_t subtree = NULL;
if (NULL != tree) {
subtree = tree->right;
tree->right = subtree->left;
subtree->left = tree;
}
return subtree;
}
```
. . .
* Et la rotation à droite (5min)?
. . .
```C
tree_t rotation_right(tree_t tree) {
tree_t subtree = NULL;
if (NULL != tree) {
subtree = tree->left;
tree->left = subtree->right;
subtree->right = tree;
}
return subtree;
}
```
# Exemple de rotation (1/2)
## Insertion de 9?
```{.mermaid format=pdf width=400 loc=figs/}
graph TD;
id0((5))-->id1((1));
id0-->id2((6));
id2-->id3(( ));
id2-->id4((8));
style id3 fill:#fff,stroke:#fff
```
# Exemple de rotation (2/2)
::: columns
:::: column
## Quelle rotation et sur quel noeud (5 ou 6)?
```{.mermaid format=pdf width=400 loc=figs/}
graph TD;
id0((5))-->id1((1));
id0-->id2((6));
id2-->id3(( ));
id2-->id4((8));
id4-->id5(( ));
id4-->id6((9));
style id3 fill:#fff,stroke:#fff
style id5 fill:#fff,stroke:#fff
```
::::
:::: column
. . .
## Sur le plus jeune évidemment!
```{.mermaid format=pdf width=400 loc=figs/}
graph TD;
id0((5))-->id1((1));
id0-->id2((8));
id2-->id3((6));
id2-->id4((9));
```
::::
:::
* Cas `1a/b` *check*!
# La rotation gauche-droite
## Là c'est plus difficile (cas 2a/b)
![La double rotation de l'enfer.](figs/double_rotation_gauche_droite.png)
# Exercices
## Faire l'implémentation de la double rotation (pas corrigé, 5min)
# Exercices
::: columns
:::: column
## Insérer 50, ex 10min (matrix)
```{.mermaid format=pdf width=400 loc=figs/}
graph TD;
id0((89))-->id1((71));
id0-->id2((90));
id1-->id3((44));
id3-->id4((37));
id3-->id5((61));
id1-->id6((81))
id2-->id7(( ))
id2-->id8((100))
style id7 fill:#fff,stroke:#fff
```
::::
:::: column
. . .
## Où se fait la rotation?
```{.mermaid format=pdf width=400 loc=figs/}
graph TD;
id0((89))-->id1((71));
id0-->id2((90));
id1-->id3((44));
id3-->id4((37));
id3-->id5((61));
id1-->id6((81))
id2-->id7(( ))
id2-->id8((100))
id5-->id9((50))
id5-->id10(( ))
style id7 fill:#fff,stroke:#fff
style id10 fill:#fff,stroke:#fff
```
::::
:::
# Exercices
::: columns
:::: column
## Rotation gauche en 44
```{.mermaid format=pdf width=400 loc=figs/}
graph TD;
id0((89))-->id1((71));
id0-->id2((90));
id1-->id3((61));
id1-->id10((81));
id3-->id4((44));
id3-->id5(( ));
id4-->id6((37))
id4-->id7((50))
id2-->id8(( ))
id2-->id9((100))
style id5 fill:#fff,stroke:#fff
style id8 fill:#fff,stroke:#fff
```
::::
:::: column
. . .
## Rotation à droite en 71
```{.mermaid format=pdf width=400 loc=figs/}
graph TD;
id0((89))-->id1((61));
id0-->id2((90));
id1-->id3((44));
id1-->id10((71));
id3-->id4((37));
id3-->id5((50));
id2-->id8(( ));
id2-->id9((100));
id10-->id11(( ))
id10-->id12((81))
style id8 fill:#fff,stroke:#fff
style id11 fill:#fff,stroke:#fff
```
::::
:::
# Exercice de la mort
Soit l’arbre AVL suivant:
::: columns
:::: column
```{.mermaid format=pdf width=400 loc=figs/}
graph TD;
id0((60))-->id1((40));
id0-->id2((120));
id1-->id3((20));
id1-->id4((50));
id3-->id5((10));
id3-->id6((30));
id2-->id7((100));
id2-->id8((140));
id7-->id9((80))
id7-->id10((110))
id9-->id11((70))
id9-->id12((90))
id8-->id13((130))
id8-->id14((160))
id14-->id15((150))
id14-->id16((170))
```
::::
:::: column
1. Montrer les positions des insertions de feuille qui conduiront à un arbre
désequilibré.
2. Donner les facteurs d’equilibre.
3. Dessiner et expliquer les modifications de l’arbre lors de l’insertion de la
valeur `65`. On mentionnera les modifications des facteurs
d’équilibre.
::::
:::
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment