1#include <iostream>
2#include <algorithm>
3using namespace std;
4
5class Node { // Un nœud contient sa valeur et des pointeurs vers ses deux enfants
6private: // Attributs privés : seules les méthodes y touchent
7 int value;
8 Node* left;
9 Node* right;
10public:
11 Node(int v) : value(v), left(nullptr), right(nullptr) {}
12 int getValue() const { return value; }
13 Node* getLeft() const { return left; }
14 Node* getRight() const { return right; }
15 void setValue(int v) { value = v; }
16 void setLeft(Node* n) { left = n; }
17 void setRight(Node* n) { right = n; }
18};
19
20int height(Node* n) { // Hauteur : une feuille vaut 1 et un emplacement vide (nullptr) vaut 0
21 if (n == nullptr) return 0;
22 return 1 + max(height(n->getLeft()), height(n->getRight()));
23}
24
25int balanceFactor(Node* n) { // Facteur d'équilibre : hauteur gauche moins hauteur droite
26 return height(n->getLeft()) - height(n->getRight());
27}
28
29Node* rotateRight(Node* y) { // Rotation simple à droite : l'enfant gauche x monte et y descend
30 Node* x = y->getLeft();
31 y->setLeft(x->getRight());
32 x->setRight(y);
33 return x;
34}
35
36Node* rotateLeft(Node* x) { // Rotation simple à gauche : l'enfant droit y monte et x descend
37 Node* y = x->getRight();
38 x->setRight(y->getLeft());
39 y->setLeft(x);
40 return y;
41}
42
43Node* rebalance(Node* n) { // Renvoie la racine du sous-arbre, équilibré
44 int bf = balanceFactor(n); // Le facteur d'équilibre du nœud est calculé
45 if (bf > 1) { // Déséquilibre à gauche. Si l'enfant gauche n'est pas déséquilibré à droite, c'est le cas LL
46 if (balanceFactor(n->getLeft()) < 0) // L'enfant gauche est déséquilibré à droite : cas LR, rotation à gauche d'abord
47 n->setLeft(rotateLeft(n->getLeft())); // Première rotation du cas LR
48 return rotateRight(n); // Rotation à droite : résout LL et la seconde moitié de LR
49 }
50 if (bf < -1) { // Déséquilibre à droite. Si l'enfant droit n'est pas déséquilibré à gauche, c'est le cas RR
51 if (balanceFactor(n->getRight()) > 0) // L'enfant droit est déséquilibré à gauche : cas RL, rotation à droite d'abord
52 n->setRight(rotateRight(n->getRight())); // Première rotation du cas RL
53 return rotateLeft(n); // Rotation à gauche : résout RR et la seconde moitié de RL
54 }
55 return n; // Le facteur est entre -1 et 1 : aucune rotation nécessaire
56}
57
58Node* insert(Node* root, int v) { // Insère v dans l'arbre AVL et renvoie la racine
59 if (root == nullptr) // Emplacement vide : le nouveau nœud va ici
60 return new Node(v); // Crée le nouveau nœud
61 if (v < root->getValue()) // Les valeurs plus petites vont à gauche et les plus grandes à droite
62 root->setLeft(insert(root->getLeft(), v)); // Descend dans le sous-arbre gauche
63 else
64 root->setRight(insert(root->getRight(), v)); // Descend dans le sous-arbre droit
65 return rebalance(root); // Au retour de chaque appel, l'équilibre du nœud est vérifié
66}
67
68int main() {
69 Node* root = buildTree(); // L'arbre affiché, déjà construit
70 root = insert(root, v); // Premier appel, depuis main
71 return 0; // Fin de l'opération
72}