Las rotaciones mantienen el equilibrio de un árbol AVL sin romper la propiedad de orden de un BST. Cada operación es local, de costo constante, y se decide según el factor de balance (FB) del nodo desbalanceado y de su hijo.
Detección rápida de casos:
Corrige un desbalance izquierda-izquierda (LL) cuando un nodo tiene FB = +2 y su hijo izquierdo tiene FB ≥ 0.
Intuición: el hijo izquierdo sube a raíz del subárbol y el nodo desbalanceado pasa a ser su hijo derecho; el subárbol derecho original del hijo izquierdo (t2) se reubica como hijo izquierdo del nodo desbalanceado.
AvlNode *rotarDerecha(AvlNode *y) {
AvlNode *x = y->izquierdo;
AvlNode *t2 = x->derecho;
x->derecho = y;
y->izquierdo = t2;
actualizarAltura(y);
actualizarAltura(x);
return x;
}
Después de mover subárboles, se recalculan alturas de abajo hacia arriba: primero y, luego x. El costo es O(1) porque solo se ajustan unos pocos punteros.
Simétrica a la anterior. Se usa en desbalances derecha-derecha (RR) con FB = -2 y el hijo derecho con FB ≤ 0.
El hijo derecho sube y el nodo desbalanceado pasa a ser hijo izquierdo; el subárbol izquierdo del antiguo hijo derecho (t2) se convierte en hijo derecho del nodo original.
AvlNode *rotarIzquierda(AvlNode *y) {
AvlNode *x = y->derecho;
AvlNode *t2 = x->izquierdo;
x->izquierdo = y;
y->derecho = t2;
actualizarAltura(y);
actualizarAltura(x);
return x;
}
La simetría permite reutilizar la misma lógica y sólo invertir punteros, manteniendo la propiedad de orden.
Resuelve un desbalance izquierda-derecha (LR): FB del nodo es +2 y el hijo izquierdo tiene FB negativo.
El primer paso convierte el caso en un desbalance LL, listo para la rotación final a la derecha.
AvlNode *rotacionIzquierdaDerecha(AvlNode *nodo) {
nodo->izquierdo = rotarIzquierda(nodo->izquierdo);
return rotarDerecha(nodo);
}
Se actualizan alturas en cada llamada interna, por lo que no se requieren ajustes extra después del segundo giro.
Aplica al caso derecha-izquierda (RL): FB del nodo es -2 y el hijo derecho tiene FB positivo.
El primer giro convierte el desbalance en un caso RR que se soluciona con la rotación final a la izquierda.
AvlNode *rotacionDerechaIzquierda(AvlNode *nodo) {
nodo->derecho = rotarDerecha(nodo->derecho);
return rotarIzquierda(nodo);
}
En ambos casos dobles, el reequilibrio se logra con dos rotaciones simples, manteniendo la propiedad de BST y ajustando alturas en cada llamada.
Notas prácticas: