1#include <iostream>
2#include <algorithm>
3using namespace std;
4
5class Node { // Un nodo guarda su valor y los punteros a sus dos hijos
6private: // Atributos privados: solo se tocan con los métodos
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) { // Altura: una hoja vale 1 y un hueco (nullptr) vale 0
21 if (n == nullptr) return 0;
22 return 1 + max(height(n->getLeft()), height(n->getRight()));
23}
24
25int balanceFactor(Node* n) { // Factor de equilibrio: altura izquierda menos altura derecha
26 return height(n->getLeft()) - height(n->getRight());
27}
28
29Node* rotateRight(Node* y) { // Rotación simple a la derecha: el hijo izquierdo x sube y y baja
30 Node* x = y->getLeft();
31 y->setLeft(x->getRight());
32 x->setRight(y);
33 return x;
34}
35
36Node* rotateLeft(Node* x) { // Rotación simple a la izquierda: el hijo derecho y sube y x baja
37 Node* y = x->getRight();
38 x->setRight(y->getLeft());
39 y->setLeft(x);
40 return y;
41}
42
43Node* rebalance(Node* n) { // Devuelve la raíz del subárbol ya equilibrada
44 int bf = balanceFactor(n); // Se calcula el factor de equilibrio del nodo
45 if (bf > 1) { // Pesa a la izquierda. Si el hijo izquierdo no pesa a la derecha es el caso LL
46 if (balanceFactor(n->getLeft()) < 0) // El hijo izquierdo pesa a la derecha: caso LR, primero se rota a la izquierda
47 n->setLeft(rotateLeft(n->getLeft())); // Primera rotación del caso LR
48 return rotateRight(n); // Rotación a la derecha: resuelve LL y la segunda parte de LR
49 }
50 if (bf < -1) { // Pesa a la derecha. Si el hijo derecho no pesa a la izquierda es el caso RR
51 if (balanceFactor(n->getRight()) > 0) // El hijo derecho pesa a la izquierda: caso RL, primero se rota a la derecha
52 n->setRight(rotateRight(n->getRight())); // Primera rotación del caso RL
53 return rotateLeft(n); // Rotación a la izquierda: resuelve RR y la segunda parte de RL
54 }
55 return n; // El factor está entre -1 y 1: no hace falta rotar
56}
57
58Node* insert(Node* root, int v) { // Inserta v en el árbol AVL y devuelve la raíz
59 if (root == nullptr) // Hueco vacío: aquí va el nodo nuevo
60 return new Node(v); // Crea el nodo nuevo
61 if (v < root->getValue()) // Los menores van a la izquierda y los mayores a la derecha
62 root->setLeft(insert(root->getLeft(), v)); // Baja por el subárbol izquierdo
63 else
64 root->setRight(insert(root->getRight(), v)); // Baja por el subárbol derecho
65 return rebalance(root); // Al volver de cada llamada se comprueba el equilibrio del nodo
66}
67
68int main() {
69 Node* root = buildTree(); // El árbol mostrado, ya construido
70 root = insert(root, v); // Primera llamada, desde main
71 return 0; // Fin de la operación
72}