-
orestis.malaspin authoredorestis.malaspin authored
- Questions sur les notions du dernier cours
- Exemple de tri par tas (1/N)
- Exemple de tri par tas (2/N)
- Exemple de tri par tas (3/N)
- Exemple de tri par tas (4/N)
- Exemple de tri par tas (5/N)
- Exemple de tri par tas (6/N)
- Exemple de tri par tas (7/N)
- Exemple de tri par tas (8/N)
- Exemple de tri par tas (9/N)
- Exemple de tri par tas (10/N)
- Exemple de tri par tas (11/N)
- Exemple de tri par tas (12/N)
- Exemple de tri par tas (13/N)
- Exercice (10min)
- L'algorithme du tri par tas (1/4)
- Deux étapes
- Pseudo-code d'entassement de l'arbre (5 min, matrix)
- L'algorithme du tri par tas (2/4)
- L'algorithme du tri par tas (3/4)
- Implémenter en C l'algorithme du tri par tas (matrix, 20min)
- L'algorithme du tri par tas (4/4)
- Fonctions utilitaires
- Complexités
- Complexité de la recherche
- Un meilleur arbre
- Définition
- Équilibre parfait ou pas?
- Équilibre parfait ou pas?
- Arbres AVL
- Définition
- Notation
- AVL ou pas?
- AVL ou pas?
- Insertion dans un arbre AVL (1/N)
- Insertion dans un arbre AVL (2/N)
- Insertion dans un arbre AVL (3/N)
- Les cas de déséquilibre
- Cas 1a
- Cas 1a
- Les cas de déséquilibre
- Cas 1b (symétrique 1a)
- Cas 1b (symétrique 1a)
- Les cas de déséquilibre
- Cas 2a
- Cas 2a
- Les cas de déséquilibre
- Cas 2b (symétrique 2a)
- Cas 2b (symétrique 2a)
- Le facteur d'équilibre (balance factor)
- Définition
- Valeurs possibles?
- Algorithme d'insertion
- Cas possibles
- Sous-arbre gauche (avant)
- Sous-arbre gauche (après)
- Algorithme d'insertion
- Cas possibles
- Sous-arbre droit (avant)
- Sous-arbre droit (après)
- Rééquilibrage
- Lien avec les cas vus plus tôt
- Dessiner les différents cas, sur le dessin ci-dessous
title: "Tri par tas et arbres AVL"
date: "2022-03-09"
patat:
eval:
tai:
command: fish
fragment: false
replace: true
ccc:
command: fish
fragment: false
replace: true
images:
backend: auto
Questions sur les notions du dernier cours
- Comment représenter un tableau sous forme d'arbre binaire?
. . .
- Qu'est-ce qu'un 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?
. . .
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
et7
.
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.
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
, échanger8
et5
(akamax(2, 5, 8)
)
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.
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)
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.
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)
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)
.
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)
.
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) avec4
. - Traiter la racine.
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)
.
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) avec4
. - Traiter la racine.
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)
.
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) avec1
. - Traiter la racine.
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)
.
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) avec1
. - Traiter la racine.
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)
.
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) avec2
. - Traiter la racine.
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)
.
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) avec2
. - Traiter la racine.
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)
.
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) avec1
. - Traiter la racine.
graph TD;
id0((1))-->id1((4));
id0-->id2((2));
::::
:::: column
But: Trier les tas.
-
1 <=> max(1, 4, 2)
.
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) avec2
. - Traiter la racine.
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
avec1
. - 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/4)
\footnotesize
Deux étapes
- Entassement (tamisage): transformer l'arbre en tas.
- Échanger la racine avec le dernier élément et entasser la racine.
Pseudo-code d'entassement de l'arbre (5 min, matrix)
. . .
tri_par_tas(tab)
entassement(tab)
échanger(tab[0], tab[size(tab)-1])
pour i = size(tab)-1 à 2
promotion(tab, 0)
échanger(tab[0], tab[i-1])
entassement(tab)
pour i = size(tab) / 2 - 1 jusqu'à 0
promotion(tab, i)
promotion(tab, i)
ind_max = ind_max(tab, i, gauche(i), droite(i))
si i != ind_max
échanger(tab[i], tab[ind_max])
promotion(tab, ind_max)
L'algorithme du tri par tas (2/4)
- Fonctions utilitaires
int ind_max(tab, i, g, d)
ind_max = i
si tab[ind_max] < tab[l]
ind_max = l
si tab[ind_mx] < tab[r]
ind_max = r
retourne ind_max
int gauche(i)
retourne 2 * i + 1
int 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)
. . .
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
. . .
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
- En moyenne?
- Dans le pire des cas?
. . .
- O(\log_2(N))
- O(N)
::::
:::: column
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 noeuds 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
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
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
- 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 neouds:
- 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 noeuds 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
graph TD;
id0((12))-->id1((10));
id0-->id2((19));
id2-->id3((17));
id2-->id4((97));
::::
:::: column
. . .
A
V
L
::::
:::
AVL ou pas?
::: columns
:::: column
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)
- On part d'un arbre AVL.
- On insère un nouvel élément.
::: columns
:::: column
-
hd ? hg
. - Insertion de
4
?
graph TD;
id0((12))-->id1((1));
id0-->id2((19));
::::
:::: column
. . .
hd = hg
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)
- On part d'un arbre AVL.
- On insère un nouvel élément.
::: columns
:::: column
-
hd ? hg
. - Insertion de
4
?
graph TD;
id0((12))-->id1((1));
id0-->id2((19));
id2-->id3((18));
id2-->id4(( ));
style id4 fill:#fff,stroke:#fff
::::
:::: column
. . .
hd < hg
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)
- On part d'un arbre AVL.
- On insère un nouvel élément.
::: columns
:::: column
-
hd ? hg
. - Insertion de
4
?
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
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 dansu
::::
:::: column
Cas 1a
- Comment rééquilibrer?
. . .
- ramène
u
,v
w
à la même hauteur. -
v
à droite deA
(gauche deB
)
::::
:::
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
-
v1
,v2
,u
,w
même hauteur. - déséquilibre en
C
après insertion dansv2
::::
:::: column
Cas 2a
- Comment rééquilibrer?
. . .
- ramène
u
,v1
,v2
,w
à la même hauteur. -
v2
à droite deB
(gauche deC
) -
B
à droite deA
(gauche deC
) -
v1
à droite deA
(gauche deB
)
::::
:::
Les cas de déséquilibre
::: columns
:::: column
Cas 2b (symétrique 2a)
::::
:::: column
Cas 2b (symétrique 2a)
- Comment rééquilibrer?
. . .
::::
:::
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é
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(gauche(P)) = -1 => cas 1b
fe(P) = +2 && fe(gauche(P)) = +1 => cas 2b