Árboles AVL / Conjuntos
ordenados Pt.2
Iván Yesid Castellanos
Limitaciones árboles de búsqueda
binarios
Ya vimos que un árbol de búsqueda binario es una
estructura que nos permite almacenar datos
ordenados y consultarlos de forma diferente a la que
se haría en una lista, donde todas las operaciones
son del orden de la altura del árbol
Sin embargo, en el peor caso la altura del árbol
puede ser la cantidad de elementos, lo que no nos
trae ninguna ventaja en relación a la
implementación de almacenamiento con listas
Esto se solucionaría si el árbol estuviera balanceado
en todo momento
Árboles Balanceados
Un árbol binario se dice que está balanceado (por altura) si para todos los
nodos la altura de los subárboles izquierdo y derecho difieren por lo mucho
en 1
Los arboles AVL (Adelson-Velskii and Landis) son una extensión de los
árboles binarios de búsqueda, donde en cada una de las operaciones de
inserción y eliminación de elementos se tienen adicionalmente unas
operaciones de balanceo, las cuales aseguran que el árbol se mantenga
balanceado con la definición anterior
Un árbol balanceado (por altura) que tenga n elementos en peor caso
tendrá altura logϕ(n), donde ϕ es la proporción aurea (la de la serie de
Fibonacci), por lo que la complejidad de las operaciones insertar, consultar
y eliminar que es en peor caso ya no será O(h) = O(n) sino O(h) = O(log n)
Definición AVLnode
AVLtree
El árbol AVL va a tener las mismas operaciones que el BST general, pero le
agregaremos unas operaciones adicionales:
Imprimir arbol
rotaciones
simple
doble
balanceo
verificar balanceo
Adicionalmente las operaciones altura, insertar y remover tendrán algunos
cambios
printTree
Si queremos imprimir los elementos del árbol en orden ascendente
podemos hacer un recorrido inorder
height
Complejidad O(1)
Rotaciones
El árbol AVL tendrá el mismo funcionamiento que los árboles de búsqueda
binarios generales, la diferencia está en la implementación, en la cual
utilizaremos unas funciones de balanceo llamadas ‘rotaciones’
Una rotación en un BST es el cambio de la posición de un par de nodos en
un árbol de modo que este continúe siendo un BST pero que esté
balanceado
Tanto al insertar como al eliminar elementos en el árbol se realizarán las
rotaciones respectivas para mantener el árbol balanceado
Rotación Simple
Supongamos que tenemos el siguiente árbol
altura(1) = altura(2) = altura(3)
altura(a) = altura(3) + 1
El árbol está balanceado por altura
Rotación Simple
Insertamos un elemento que queda en el subárbol 1
altura(1) = altura(2) + 1
altura(a) = altura(3) + 2
Ya no está balanceado
Rotación Simple
La rotación simple consiste en volver ahora a ‘a’ la raíz del árbol, a ‘b’ el
subárbol izquierdo con hijos 2 (izquierdo) y 3 (derecho)
altura(1) = altura(2) + 1
altura(b) = altura(1)
El árbol está balanceado ☺
Rotación Simple
El árbol sigue siendo un BST
El árbol sigue siendo binario
Elementos de 1 son menores que a y b
Elementos de 2 son mayores que a y menores que b
Elementos de 3 son mayores que a y b
a es menor que b (b es mayor que a)
rotateWithLeftChild
Complejidad O(1)
Rotación Simple
También se puede construir el caso simétrico al mostrado
anteriormente:
Donde los papeles del subárbol izquierdo y derecho del árbol se
intercambian (3 fuera el subárbol izquierdo y a fuera el hijo derecho de
b)
Ambos casos deben ser considerados en el código para que no
haya desbalanceo del árbol
También es posible que toque realizar una rotación simple en caso
de eliminación
En el caso de la inserción este funciona cuando ocurre en subárboles
exteriores (left – left o right - right)
¿Qué pasa cuando se inserte en subárboles interiores?
Rotación Doble
Consideremos el siguiente caso
altura(2) = altura(3)
altura(1) = altura(4) = altura(2) + 1
altura(a) = altura(4) + 1
El árbol está balanceado
Rotación Doble
Insertando en el subárbol 2
altura(2) = altura(3) + 1
altura(4) = altura(2)
altura(a) = altura(4) + 2
El árbol no está balanceado
Rotación Doble
Si tratáramos de hacer rotación simple
altura(2) = altura(3) + 1
altura(1) = altura(2)
altura(b) = altura(1) + 2
El árbol sigue desbalanceado
Rotación Doble
Hacer rotación simple de ‘a’ con ‘c’
altura(4) = altura(3) + 1
altura(1) = altura(2) = altura(4)
altura(c) = altura(4) + 2
Rotación Doble
Hacer rotación simple de ‘b’ con ‘c’
altura(4) = altura(3) + 1
altura(1) = altura(2) = altura(4)
altura(a) = altura(b)
El árbol está balanceado de nuevo ☺
doubleWithLeftChild
Complejidad O(1)
Rotación Doble
También se puede construir el caso simétrico al mostrado
anteriormente:
Donde los papeles del subárbol izquierdo y derecho del árbol se
intercambian (4 fuera el subárbol izquierdo y a fuera el hijo derecho de
b)
Ambos casos deben ser considerados en el código para que no
haya desbalanceo del árbol
También es posible que toque realizar una rotación doble en caso de
eliminación
Balance
Verifica en algún momento cual de las rotaciones toca hacer (si toca
hacer) y la hace
CheckBalance
Verifica si un árbol está balanceado por altura o no
Test AVLtree
Si corremos la misma prueba
que utilizamos para arboles
BST generales el resultado de
findMin y contains debe ser
igual, sin embargo, se espera
que las altura sean menores
o iguales a las realizadas en
el BST general, por las
operaciones de balanceo.
Conjunto Ordenado (Set, TreeSet)
Una estructura de conjunto ordenado en su interior maneja un BST
balanceado, una posibilidad es que esté implementado con arboles AVL,
la ventaja de estos es que nos permiten almacenar, remover y consultar
elementos de forma eficiente
En Java Collections esta estructura es la llamada TreeSet, en STL (c++) es el
set
Para utilizar estas estructuras los objetos que se almacenen deben tener
algún ordenamiento (un comparador bien definido)
Otros arboles balanceables
Arboles Rojo-Negros (Red-black trees): son
arboles donde cada nodo en lugar de
almacenar una altura almacena un color
(rojo o negro) que tiene las siguientes
propiedades:
La raíz es negra
Las hojas tienen hijos (null) que son de color
negro
Si un nodo es rojo, entonces ambos hijos
son negros
Todo camino de un nodo a cualquier
descendiente tiene siempre la misma
cantidad de nodos negros
Otros arboles balanceables
Un árbol rojo-negro (un árbol que cumpla
las propiedades anteriormente
mencionadas) estará cuasi balanceado
por altura, pues la distancia de la raíz a la
hoja mas profunda será a lo sumo 2 veces
la distancia de la raíz a la hoja menos
profunda
Las operaciones insertar y remover en este
árbol se hacen de modo que siempre se
asegura que las propiedades se cumplen
en todo momento