Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Un árbol binario equilibrado mantiene su altura suficientemente baja para que buscar, insertar y eliminar elementos siga costando O(log n) en el peor caso. Su objetivo es evitar que un árbol binario de búsqueda se convierta en una cadena cuando las claves llegan, por ejemplo, en orden ascendente.
Los dos modelos más importantes son el árbol AVL, que mantiene un equilibrio más estricto, y el árbol rojo-negro, que permite más flexibilidad a cambio de reducir normalmente el coste de las reorganizaciones. Ambos conservan las claves ordenadas y se reajustan después de modificaciones.
Qué problema resuelve el equilibrio
En un árbol binario de búsqueda (BST), las claves menores que un nodo se colocan a la izquierda y las mayores a la derecha. Si se insertan las claves 10, 20, 30, 40, 50 en ese orden y no se aplica ninguna estrategia de equilibrio, el árbol puede adoptar una forma parecida a una lista:
10
20
30
40
50
La operación deja de descartar aproximadamente la mitad de los elementos en cada comparación. Buscar, insertar o eliminar puede requerir recorrer todos los nodos, con coste O(n). Un árbol autobalanceado reorganiza localmente sus enlaces después de insertar o eliminar para mantener una altura logarítmica.
#1 Best Overall
La cota O(log n) es una garantía de crecimiento, no una promesa de que todas las implementaciones tengan el mismo tiempo real. Influyen el coste de comparar claves, las asignaciones de memoria, la localidad de caché y los metadatos de cada nodo.
Runestone Academy explica la relación entre la altura de un BST y el deterioro de sus operaciones.
Conceptos básicos
Árbol binario
Un árbol binario es una estructura en la que cada nodo tiene como máximo dos hijos: uno izquierdo y uno derecho.
Árbol binario de búsqueda
En un BST, para cada nodo con clave k:
- las claves del subárbol izquierdo son menores que
k; - las claves del subárbol derecho son mayores que
k; - la política para claves duplicadas debe estar definida.
Los duplicados pueden rechazarse, contarse dentro del nodo, almacenarse como una colección asociada o colocarse sistemáticamente a un lado. Lo importante es que la comparación sea coherente.
El recorrido inorden —izquierdo, nodo, derecho— produce las claves ordenadas. Esta propiedad debe mantenerse también después de cada rotación.
Altura
En este artículo, la altura es el número de aristas del camino más largo desde un nodo hasta una hoja. Con esta convención, una hoja tiene altura 0; un hijo nulo suele representarse con altura -1. Algunas implementaciones cuentan niveles y asignan otros valores iniciales. La elección modifica los números, pero no las complejidades.
Equilibrio, completitud y perfección
“Equilibrado” no significa necesariamente “perfecto” ni “completo”. Un árbol perfecto tiene todos los niveles llenos. Uno completo llena los niveles de arriba abajo y de izquierda a derecha, con posibles huecos solo en el último nivel. Un árbol equilibrado, en cambio, usa algún criterio para limitar su altura; puede tener una forma irregular y seguir siendo válido.
Recommended Free Tools
Tampoco existe una única definición universal de equilibrio. Puede basarse en diferencias de alturas, colores, pesos u otras invariantes. Por eso siempre hay que especificar qué estructura se está utilizando.
Qué significa autobalancearse
Un árbol autobalanceado no mantiene una forma visual perfectamente simétrica. Mantiene una serie de invariantes y se reorganiza cuando una inserción o eliminación las rompe.
En AVL, la regla se expresa mediante alturas. En rojo-negro, mediante colores y el número de nodos negros en los caminos. Las rotaciones son transformaciones locales que cambian la forma del árbol sin cambiar el orden producido por el recorrido inorden.
Rank #2
- color: White
- INTRODUCTION TO ALGORITHMS, FOURTH EDITION
Árbol AVL
Un árbol AVL es un árbol binario de búsqueda en el que, para cada nodo, las alturas de sus dos subárboles difieren como máximo en una unidad:
|h(izquierdo) - h(derecho)| ≤ 1
Usaremos este factor de equilibrio:
FE(n) = h(n.izquierdo) - h(n.derecho)
Un nodo válido tiene un factor de -1, 0 o 1. Los valores 2 y -2 indican que hay que reequilibrar. Algunas fuentes invierten el signo; ambas convenciones son válidas si se aplican de forma uniforme.
Información que suele guardar cada nodo
clave
valor
hijo_izquierdo
hijo_derecho
altura
También puede almacenarse directamente el factor de equilibrio. La altura se actualiza con:
altura(n) = 1 + max(altura(n.izquierdo), altura(n.derecho))
Guardar la altura evita recalcular todo el subárbol después de cada modificación. Las rotaciones individuales cuestan O(1) y la altura total de un AVL es O(log n); por ello, búsqueda, inserción y eliminación tienen coste O(log n) en el peor caso.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →La implementación de AVL de Runestone muestra cómo actualizar factores y reequilibrar el árbol.
Las cuatro rotaciones AVL
Una rotación debe conservar la propiedad de búsqueda. Los subárboles A, B, C y D representan grupos completos de nodos, no nodos individuales necesariamente.
Caso LL: rotación simple a la derecha
Se produce cuando el desequilibrio está en el subárbol izquierdo del hijo izquierdo. Con nuestra convención, el nodo z queda con factor 2.
z y
/ /
y D → A z
/ /
A C C D
La solución es una rotación derecha sobre z.
Caso RR: rotación simple a la izquierda
El desequilibrio está en el subárbol derecho del hijo derecho. El nodo z queda con factor -2.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11 z y
/ /
A y → z D
/ /
C D A C
La solución es una rotación izquierda sobre z.
Caso LR: rotación doble izquierda-derecha
El hijo izquierdo está cargado hacia la derecha:
z z x
/ / /
y D → x D → y z
/ / / /
A x y C A B C D
/ /
B C A B
- Rotar a la izquierda el hijo izquierdo
y. - Rotar a la derecha el nodo desequilibrado
z.
Caso RL: rotación doble derecha-izquierda
El hijo derecho está cargado hacia la izquierda:
z z x
/ / /
A y → A x → z y
/ / / /
x D B y A B C D
/ /
B C C D
- Rotar a la derecha el hijo derecho
y. - Rotar a la izquierda el nodo
z.
Después de una rotación, primero se actualizan los enlaces y después las alturas. El nodo que ha descendido debe actualizarse antes que el que ha ascendido. Además, la función debe devolver la nueva raíz del subárbol.
Rank #3
La documentación de ibiblio incluye explicaciones y diagramas de las rotaciones AVL.
Inserción en un AVL
La inserción sigue inicialmente el mismo camino que en un BST:
- Si el nodo actual es nulo, crear el nuevo nodo.
- Descender a la izquierda si la clave es menor.
- Descender a la derecha si es mayor.
- Aplicar la política elegida si la clave ya existe.
- Al regresar hacia la raíz, actualizar alturas.
- Calcular el factor de equilibrio.
- Aplicar una rotación simple o doble cuando el factor sea
2o-2.
insertar(nodo, clave):
si nodo es nulo:
devolver nuevo nodo(clave)
si clave < nodo.clave:
nodo.izquierdo = insertar(nodo.izquierdo, clave)
si clave > nodo.clave:
nodo.derecho = insertar(nodo.derecho, clave)
si clave == nodo.clave:
aplicar la política de duplicados
nodo.altura = 1 + max(altura(nodo.izquierdo),
altura(nodo.derecho))
factor = altura(nodo.izquierdo) - altura(nodo.derecho)
si factor > 1 y clave < nodo.izquierdo.clave:
devolver rotar_derecha(nodo)
si factor < -1 y clave > nodo.derecho.clave:
devolver rotar_izquierda(nodo)
si factor > 1 y clave > nodo.izquierdo.clave:
nodo.izquierdo = rotar_izquierda(nodo.izquierdo)
devolver rotar_derecha(nodo)
si factor < -1 y clave < nodo.derecho.clave:
nodo.derecho = rotar_derecha(nodo.derecho)
devolver rotar_izquierda(nodo)
devolver nodo
La llamada debe reasignar la raíz:
raiz = insertar(raiz, clave)
Si se ignora el valor devuelto, una rotación en la raíz puede desconectar parte del árbol o dejar al programa usando una raíz antigua.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Eliminación en un AVL
Eliminar es más delicado porque la reducción de altura de un subárbol puede desequilibrar varios ancestros consecutivos.
- Localizar el nodo.
- Si es una hoja, eliminarlo.
- Si tiene un solo hijo, sustituirlo por ese hijo.
- Si tiene dos hijos, copiar la clave del sucesor inorden —el menor nodo del subárbol derecho— o del predecesor inorden y eliminar después ese nodo.
- Actualizar las alturas al volver hacia la raíz.
- Reequilibrar cada ancestro afectado hasta llegar a la raíz.
En una inserción, con frecuencia el primer reequilibrio detiene la propagación de cambios de altura; en una eliminación no conviene asumirlo. Hay que seguir revisando el camino completo. La eliminación sigue siendo O(log n), pero su implementación tiene más casos y más posibilidades de error.
Árboles rojo-negro
Un árbol rojo-negro es otro BST autobalanceado. Cada nodo tiene un atributo adicional: color rojo o negro. Sus invariantes habituales son:
- Cada nodo es rojo o negro.
- La raíz es negra.
- Las hojas nulas o centinelas se consideran negras.
- Un nodo rojo no puede tener un hijo rojo.
- Todo camino desde un nodo hasta sus hojas nulas descendientes contiene el mismo número de nodos negros.
Estas reglas limitan la altura a O(log n), aunque permiten más desequilibrio que AVL. El reequilibrio combina rotaciones y recoloreados. Búsqueda, inserción y eliminación tienen coste O(log n) en el peor caso.
Free tools Windows power users keep installed
One-click scans. No signup required.
Consulta las propiedades formales del árbol rojo-negro.
AVL frente a rojo-negro
| Criterio | AVL | Rojo-negro |
|---|---|---|
| Equilibrio | Más estricto; limita más la diferencia de alturas. | Más flexible; controla la altura mediante colores. |
| Búsqueda | Puede recorrer una altura menor. | O(log n) garantizado, aunque el árbol puede ser algo más alto. |
| Inserción | Actualiza alturas y puede rotar. | Recolorea y puede rotar. |
| Eliminación | Puede requerir reequilibrar varios ancestros. | También es compleja, pero suele favorecer menos modificaciones estructurales. |
| Metadatos | Altura o factor de equilibrio. | Color y, normalmente, referencias a padres o nodos centinela. |
| Uso típico | Muchas búsquedas y relativamente pocas modificaciones. | Mezcla general de búsquedas, inserciones y eliminaciones. |
No es correcto afirmar que AVL sea siempre mejor o que rojo-negro sea siempre más rápido. AVL puede favorecer una carga dominada por lecturas porque mantiene una altura más estricta. Rojo-negro suele ser una opción generalista cuando hay muchas actualizaciones. La decisión real depende también de la implementación, el patrón de claves, las comparaciones y el comportamiento de memoria.
Complejidad
| Operación | AVL | Rojo-negro |
|---|---|---|
| Búsqueda | O(log n) |
O(log n) |
| Inserción | O(log n) |
O(log n) |
| Eliminación | O(log n) |
O(log n) |
| Mínimo o máximo | O(log n), o O(1) con una referencia adicional |
O(log n), o O(1) con una referencia adicional |
| Recorrido inorden | O(n) |
O(n) |
| Rotación | O(1) |
O(1) |
| Espacio | O(n) |
O(n) |
El recorrido de todos los elementos cuesta O(n) porque debe visitar cada nodo. El equilibrio no convierte una operación que examina todo el árbol en una operación constante.
Uso en Java, C++ y Python
Java: TreeMap y TreeSet
TreeMap mantiene las claves ordenadas según su orden natural o un Comparator. Su documentación garantiza coste logarítmico para containsKey, get, put y remove; está basado en un árbol rojo-negro.
TreeSet se apoya en TreeMap y ofrece coste logarítmico garantizado para add, remove y contains.
TreeMap<Integer, String> edades = new TreeMap<>();
edades.put(25, "Ana");
edades.put(19, "Luis");
System.out.println(edades.firstKey());
System.out.println(edades.subMap(20, true, 30, true));
Las claves deben poder compararse entre sí. El comparador debe ser coherente con la noción de igualdad que espera la colección; de lo contrario, dos objetos que el programa considera distintos pueden ocupar la misma posición lógica, o viceversa.
TreeMap no es automáticamente seguro para modificaciones estructurales concurrentes. La documentación de Java requiere sincronización externa o el uso de una alternativa apropiada cuando varios hilos acceden y modifican la estructura.
Documentación oficial de TreeMap y documentación oficial de TreeSet.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
C++: std::map
std::map es un contenedor asociativo ordenado. Sus operaciones de búsqueda, inserción y eliminación tienen complejidad logarítmica. Las implementaciones suelen utilizar árboles rojo-negro, pero el estándar fija requisitos de comportamiento y complejidad, no obliga necesariamente a un mecanismo interno concreto.
std::map<int, std::string> edades;
edades[25] = "Ana";
edades[19] = "Luis";
for (const auto& [edad, nombre] : edades) {
// Se recorre en orden de clave
}
Consulta los requisitos y complejidades documentados para std::map.
Python: bisect no sustituye a un árbol
El módulo estándar bisect permite encontrar una posición en una lista ordenada mediante búsqueda binaria. Sin embargo, insertar el elemento en esa posición sigue costando O(n) porque los elementos posteriores deben desplazarse.
from bisect import bisect_left
valores = [10, 20, 40]
pos = bisect_left(valores, 30)
valores.insert(pos, 30) # El desplazamiento puede costar O(n)
Una lista ordenada con bisect puede ser una excelente solución para conjuntos pequeños o lecturas frecuentes, pero no ofrece las mismas garantías de actualización que un árbol equilibrado. La documentación de Python detalla el coste de las inserciones.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteCuándo elegir cada estructura
Árbol equilibrado
Es una buena opción cuando se necesita:
- mantener los elementos ordenados dinámicamente;
- buscar sucesores y predecesores;
- realizar consultas por rango;
- obtener mínimos y máximos mientras cambian los datos;
- recorrer los elementos en orden;
- conservar una garantía de peor caso logarítmica.
Tabla hash
Una tabla hash suele ser preferible si solo importa localizar una clave exacta, no se necesita orden ni consultas de rango y se acepta una garantía esperada o amortizada. En Java, HashMap no garantiza un orden de iteración; TreeMap sacrifica parte de la ventaja esperada de una tabla hash para mantener el orden y ofrecer operaciones logarítmicas garantizadas.
Best Value
- Binding: paperback
- Language: english
- It ensures you get the best usage for a longer period
Documentación oficial de HashMap.
Otras alternativas
- Árboles B o B+: adecuados cuando los datos residen principalmente en disco o almacenamiento externo.
- Estructuras concurrentes ordenadas: necesarias cuando la sincronización y el acceso simultáneo son requisitos centrales.
- Árboles persistentes: útiles cuando se necesitan versiones inmutables de la estructura.
- Arreglos ordenados: convenientes para datos estáticos, especialmente por su localidad de memoria.
- Treaps u otras variantes: alternativas cuando se desea una combinación distinta de simplicidad y garantías probabilísticas.
Errores comunes al implementar un AVL
No reasignar la raíz
Una rotación puede cambiar la raíz de un subárbol o del árbol completo. Por eso la llamada debe conservar el resultado:
raiz = insertar(raiz, clave)
Actualizar mal las alturas
Tras una rotación, actualiza primero la altura del nodo que baja y después la del nodo que sube. Si el orden se invierte, el segundo cálculo puede usar información obsoleta.
Confundir el signo del factor
Con FE = altura(izquierdo) - altura(derecho), un factor positivo grande significa desequilibrio hacia la izquierda. Si se usa la fórmula contraria, los signos de todos los casos deben invertirse.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Romper el orden BST
Una rotación correcta cambia enlaces, pero conserva el orden inorden. Recorrer el árbol después de una operación permite detectar enlaces mal reasignados.
No definir duplicados
El comportamiento ante una clave existente debe estar documentado. Ignorar este caso suele causar conteos incorrectos o nodos que no pueden localizarse de forma consistente.
Mezclar convenciones de altura
Si un hijo nulo tiene altura -1 en una función y 0 en otra, los factores serán erróneos. Elige una convención y úsala en creación, actualización y validación.
Confundir complejidad con tiempo constante
O(log n) sigue creciendo con el número de nodos. Además, cada recorrido implica comparaciones y accesos indirectos a memoria.
Free tools Windows power users keep installed
One-click scans. No signup required.
Ignorar la comparación
Una comparación costosa puede dominar el tiempo total. También es peligroso utilizar un comparador que no establezca un orden coherente, porque el árbol puede quedar lógicamente corrupto aunque sus enlaces parezcan válidos.
Cómo validar una implementación
Las pruebas deben comprobar invariantes, no solo algunos resultados de búsqueda. Después de cada inserción y eliminación conviene verificar:
- Orden BST: el recorrido inorden está ordenado según el comparador.
- Alturas almacenadas: cada altura coincide con la altura calculada recursivamente.
- Factor AVL: cada nodo tiene un factor dentro de
[-1, 1]. - Enlaces: no existen ciclos ni referencias inesperadas.
- Conteo: el número de nodos coincide con las claves únicas o con la política de duplicados.
- Raíz: la raíz devuelta se reasigna después de todas las operaciones.
Incluye secuencias adversas: claves ascendentes, descendentes, datos ya ordenados, inserciones aleatorias, eliminaciones de hojas, nodos con un hijo y nodos con dos hijos. También prueba eliminaciones consecutivas que obliguen a reequilibrar varios niveles.
Qué no es un árbol binario equilibrado
- No es un heap: un heap facilita obtener el mínimo o el máximo, pero no ofrece búsqueda binaria ordenada general.
- No es una tabla hash: la tabla hash prioriza el acceso exacto, mientras que el árbol mantiene orden y rangos.
- No es necesariamente completo: un AVL puede tener huecos y seguir cumpliendo su condición de altura.
- No es cualquier árbol simétrico a la vista: el equilibrio debe definirse formalmente.
- No basta con ordenar una vez los datos: el árbol debe conservar sus propiedades tras actualizaciones.
- No todos los BST se equilibran solos: un BST ordinario puede degradarse hasta tener altura lineal.
Conclusión
El equilibrio resuelve el principal problema de un árbol binario de búsqueda: que su altura crezca hasta convertirse en O(n). AVL y rojo-negro conservan el orden y mantienen las operaciones fundamentales en O(log n) en el peor caso, pero lo hacen con invariantes diferentes.
Elige AVL cuando una altura más estrictamente controlada favorezca una carga dominada por búsquedas. Elige rojo-negro cuando necesites una estructura ordenada generalista con una mezcla importante de lecturas y modificaciones. Si no necesitas orden ni rangos, una tabla hash puede ser más adecuada; si los datos son estáticos o viven en disco, otras estructuras pueden ofrecer mejores propiedades.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

