Sunteți pe pagina 1din 35

AVL - ARBOLES

BALANCEADOS

Estructuras de Datos
CCPG1006
EFICIENCIA DE LOS ABB

Los ABB se utilizan para almacenar datos en forma


ordenada y facilitar la búsqueda de información. Ejemplo:
12, 18, 27 y 35
La estructura de un ABB depende del orden en que se
12
añaden sus nodos.
18

Si todos los elementos se añaden en orden creciente: 27

35
 El árbol queda alineado todo hacia la derecha

 Y la búsqueda ya no es binaria(2 posibilidades), es lineal(1)


MAS EFICIENCIA
12

18
El árbol debe guardar otra estructura.
27

Algo más equilibrado para asegurar siempre una 35


búsqueda binaria.
ABB Ineficiente,
Busqueda lineal

Que a partir de un nodo N con clave K, aprox. la


mitad tengan claves mayores que K y aprox. la otra 18
mitad tengan claves menores.
12 27
Si se asegura equilibrio, se asegura eficiencia
35

ABB Eficiente, la busqueda


siempre es binaria
ARBOLES EQUILIBRADOS

Este tipo de árboles fueron descritos en 1962 por los matemáticos rusos G. M.
Adelson-Velskii y E. M. Landis. (AVL)

Para todo nodo p del árbol:


La altura(p.
Factor der) y altura(p.
de Equilibrio = izq) nunca difieren entre sí en más de una
unidadAlt(Der) – Alt(Izq)
2
1
Alt(der) – 5
Alt(izq) = 0
5
0 0
4 8
4 8 0
Para árbol -1

equilibrado F.E. 7 10
6 10 debe ser –1, 0 o 1
-1 0

0
0
6 ARBOL NO EQUILIBRADO
0
REESTRUCTURACION

Un AVL debe conservar su equilibrio en todo momento

Al añadir o eliminar un nodo:


La altura del árbol puede cambiar.
Los factores de equilibrio deberán recalcularse.

Si al recalcular, encontramos que un fe no es ni –1 ni 0 ni 1


Hay que reestructurar el árbol: ROTARLO
INSERCION: CASOS POSIBLES

Al insertar una nueva clave pueden darse algunos casos, que dependerán de
las alturas de los subarboles(izq y der)

Tipos de Casos:
– Altura no es afectada, todo OK
– Altura es afectada y algún fe se daña, hay que decidir que tipo de
reestructuración es:
ROTACION IZQUIERDA IZQUIERDA(II)
ROTACION DERECHA DERECHA(DD)
ROTACION IZQUIERDA DERECHA(ID)
ROTACION DERECHA IZQUIERDA(DI)
CASO I: TODO OK

Cuando la altura no cambia o aunque la altura cambie, la


diferencia de alturas sigue OK
Ejemplo:
El árbol se equilibra completamente La altura cambia pero los factores se
mantienen en -1,0,1

•Si se inserta por izq, FE de la raiz


0-1
0
-1 disminuye
•Si se inserta por der, FE de la raiz 0
-1 00
0
0
aumenta
0

10
01

0 0 0 1 0

0
INSERCION: CASOS POSIBLES

Inserción en :
ROTACION IZQUIERDA IZQUIERDA(II) el subárbol izquierdo de la rama izquierda.
ROTACION DERECHA DERECHA(DD) el subárbol derecho de la rama derecha.
ROTACION IZQUIERDA DERECHA(ID) el subárbol derecho de la rama izquierda.
ROTACION DERECHA IZQUIERDA(DI) el subárbol izquierdo de la rama derecha.

rotación simple rotación doble


ROTACION SIMPLE II

El peso del árbol cae más para la izq. y hay desbalanceo


Los f.e. de
n y n1,
Rotar a partir de este nodo
quedaron 0
n
Si se detecta un f.e. -2, el cambio
18 viene por la izquierda
n1
-1-2 Si el siguiente nodo también
12 n
tiene un f.e. negativo(-1), 12
0-1
9 hay que rotar II
0
0 9 18
0 0
Al rotar n1.der = n
F.E. FUERA DE RANGO !!! n = n1
ROTACION SIMPLE II

Los f.e. de
n y n1,
n quedaron 0
18
n1
12 -1
-2 25
¿y el
0 17? 12
-1
0
9 17
9 0 18
0-1 0 Al rotar, el 18
1 debe bajar, no 0
1
-1 17 25
0 importa el 17
0 0 0
n.izq = n1.der
n1.der = n
n = n1
ROTACION II: IMPLEMENTACION

n
void RotacionII(NodoAVL<E> n){ 18
n1
-2
NodoAVL<E> n1= n.izq; 12 25
0
n.izq = n1.der; 9
-1
17
n1.der = n; -1
0
1
n = n1;
0

n.fe = n1.fe = 0;
12
} 0 18
9
0
1
-1
17 25
0 0 0
ROTACION SIMPLE DD

Similar a la rotación II, pero el mayor peso cae sobre el árbol


derecho

Los f.e. de
n
Si se detecta un f.e. 2, el cambio n y n1,
viene por la derecha (positivo) quedaron 0
18
21 n1 Si el siguiente nodo también tiene
un f.e. 1, hay que rotar DD
10 25
25
30 0
18 30
0
Al rotar 0 0
n. der = n1. izq
ALERTA, F.E. FUERA DE n1. izq = n
RANGO !!! n = n1
ROTACION DD: IMPLEMENTACION

void RotacionDD (NodoAVL<E> n){


NodoAVL<E> n1= n.der;
n.der = n1. izq;
n1. izq = n;
n = n1;
n.fe = n1.fe = 0;
}
ROTACION DOBLE ID

Si se detecta un f.e. -2, el cambio


viene por la izquierda
Si el siguiente nodo tiene un f.e. Los f.e. de
n positivo, hay que rotar ID n y n1,
18 quedaron 0
n1
-2
-1
12
n2
10
17 17
0
AL ROTAR 12 0 18
0
0
ROTACION DOBLE ID
Un f.e. -2,
ROTAR I

n
n 18
18 Si el f.e. de
n1 Si el f.e. de n2 n1
n2 es -1, al es 1, al rotar : 12 -2
-1 25
12 -1
-2 25 rotar: 0
n1.fe= -1 n2
n.fe = 1, n.fe = 10
10 0 9 16
9 17 n2 n1.fe = n2.fe n2.fe = 0
=0 0 10
0
15
0
-1 17
0
0

f.e. 1
17 16
ROTAR 0 18 0 18
ID 12 12
1 0
0 25 -1
17 25
9 15 9
0 0 0
0 0 0
ROTACION ID: IMPLEMENTACION
void RotacionID(NodoAVL<E> n){
n
NodoAVL <E> n1=n.izq, n2=n1.der; n
18 18
n1.der =n2.izq; n1 -2
n.izq = n2.der; 12 25 0
n1 -2
-1 25
12
n2.der = n; 1 n2 0
9 17 10 n2
n2.izq = n1; 9 16
0 -1
n1.fe = n.fe = 0; 0
15 10
17
if(n2.fe==-1)
0 0
n.fe = 1;
if(n2.fe==1)
n1.fe = -1;
n2.fe = 0;
n = n2; 17 16
} 18
12 0 18 12 0

0
0
1
25 -1
17 25
9 15 9
0 0 0
0 0
0
ROTACION DOBLE DI

21
n Si se detecta un f.e. 2, el cambio
viene por la derecha
18
Si el siguiente nodo tiene un f.e.
-1
0 n1 negativo, hay que rotar DI
n2 25

20
0
0
AL ROTAR
20
0 0

18 25
ROTACION DI: IMPLEMENTACION

void RotacionDI(NodoAVL<E> n){


NodoAVL<E> n1=n.izq, n2=n1.der;
n1.izq=n2.der;
n.der = n2.izq;
n2.izq = n;
n2.der = n1;
n1.fe = n.fe = 0;
if(n2.fe==-1)
n1.fe = 1;
if(n2.fe==1)
n.fe = -1;
n2.fe = 0;
n = n2;
}
ALGORITMO DE INSERCION

Bajar por el árbol hasta la posición indicada para insertar.

Crear nueva hoja e insertarla.

Al regresar por el mismo camino recalcular factor de equilibrio.


RECALCULANDO FACTORES

Luego de haber hecho la inserción, se revisa por que lado se hizo la


misma
Si se hizo del lado izquierdo: hay que Decrementar FE
Si FE era 0, ahora es –1, y su altura cambia
Si era 1, ahora es 0, quedo equilibrado, altura no cambia y todo
termina
Si era –1, ahora es –2: ROTAR, altura no cambia, y todo termina
Si se hizo del lado derecho: Aumentar FE
Si era 0, ahora es 1, y su altura cambia
Si era -1, ahora es 0, quedo equilibrado, altura no cambia y todo
termina
Si era 1, ahora es 2: ROTAR: altura no cambia y todo termina
¿COMO ELEGIR ROTACION?

Si n.fe == 2
Si n1.fe == 1, ROTACION DD
Si no ROTACION DI
Si n.fe == -2
Si n1.fe ==-1, ROTACION II
Si no ROTACION ID
EJERCICIO
Crear un AVL insertando las siguientes claves:
100, 29, 71, 82, 48, 39, 101, 22, 46, 17, 3, 20, 25, 10
INSERTAR: IMPLEMENTACION

bool AVL_Insertar(NodoAVL<E> A, E dato){


bool seguir_revisando;
if(A.estaVacio()){
A = new NodoAVL(dato);
A.fe = 0;
return true;
}
if(compare(dato, A.getData())>0){
seguir_revisando = AVL_Insertar(A.getDer(), dato);
if(seguir_revisando)
seguir_revisando = RecalcularPorDerecha(A);
}else if(compare(dato, A.getData())<0){
seguir_revisando = AVL_Insertar(A.getIzq(), dato);
if(seguir_revisando)
seguir_revisando = RecalcularPorIzquierda(A);
}else
return false;
return(seguir_revisando);
}
ACTUALIZACION POR EL LADO IZQUIERDO

bool RecalcularPorIzquierdo(NodoAVL<E> n){


switch(n.fe){
case 0: n.fe= -1
return true;
case 1: n.fe = 0 //en f.e. = 0 se detiene
return false;
case -1: //cambia a –2
if(n.izq.fe == 1){
RotarID(n);
} else
RotarII(n);
return false;
}
}
ELIMINACION DE UN NODO

Existen 2 casos, igual que en el ABB


El nodo a eliminar es un nodo hoja o con un único descendiente.
Se suprime o se sustituye por su descendiente
El nodo a eliminar tienen dos subárboles
Se busca el mayor de los menores y se intercambia
Se elimina este último nodo
Recordemos
Se debe conservar el equilibrio
CONSERVAR EL EQUILIBRIO

Así como al insertar


Regresar por el camino de búsqueda
Recalcular factores
Si se eliminó por la izquierda: aumentar
Si se eliminó por la derecha: disminuir
Si FE no es 0,-1,1: Rotar
Luego de Rotar
La altura del árbol puede haber cambiado
Si la altura cambió, hay que seguir SUBIENDO Y RECALCULANDO
Hasta que la altura no cambie más
¿COMO ELEGIR ROTACION?

Si n.fe = 2
Si n1.fe >= 0, ROTACION DD
Si no ROTACION DI

Si n.fe = -2
Si n1.fe <= 0, ROTACION II
Si no ROTACION ID
CASOS
El FE de n1 es 0,
altura no disminuye,
el FE de n queda -1
El FE de n1 es -1, y el FE de n1 queda
Al yaltura
rotar, disminuye,
la altura del árbol puede
todos los FE de
disminuir 1

los participantes
Tomemos como ejemplo la rotación II
quedan 0

II 18 II
18
3 -1
-2 25
3 12
12
-2
-1 25
0
0
-1
0 9 17
9 12
0 0
0
3 9 1 18
12
2 -1
9 0 18 No 0 17
Disminuye Disminuye
0 0
0
OTRO CASO

En las rotaciones ID y DI, la altura siempre disminuye


Veamos un ejemplo de rotación ID:

18 17
Disminuye 2
-2
-1 25 12 0 18
3 12
0 0
1 0
17
0
CONCLUSION AL ELIMINAR

En las rotaciones II En las rotaciones DD


Si n1.fe == -1, Si n1.fe == 1,
n.fe y n1.fe quedan 0 n.fe y n1.fe quedan 0
La altura disminuye La altura disminuye
Si no Si no
n.fe = -1 n.fe = 1
n1.fe = 1 n1.fe = -1
La altura permanece igual La altura permanece igual

En las rotaciones DI y ID
La altura siempre disminuye
f.e. = 0
ROTACION II:IMPLEMENTACION

• La rotación II que implementamos


– Solo observaba el caso de la Inserción
– Hay que hacer ciertos ajustes para considerar la eliminación

void RotacionII(NodoAVL<E> n){ void RotacionII(NodoAVL<E> n){


NodoAVL<E> n1= n.izq; NodoAVL<E> n1 = n.izq;
n.izq = n1.der; n.izq = n1.der;
n1.der = n; n1.der = n;
n = n1; n = n1;
n.fe = n1.fe = 0; if(n1.fe == -1)
} n.fe = n1.fe = 0;
else{
n1.fe = 1;
n.fe = -1;
}

}
ELIMINACION: ALGORITMO
• Si el árbol esta vacio, la clave buscada no esta en el árbol
• Si no, Busco
• Si clave buscada es menor que la clave evaluada
– Eliminar por el lado izquierdo
– Si la altura del árbol cambia
• Actualizar factores izquierda
• Si clave buscada es mayor que la clave evaluada
– Eliminar por el lado derecho
– Si altura del árbol cambia
• Actualizar factores derecha
• Si clave evaluada es igual a clave buscada: Eliminar nodo
– Si el nodo solo tiene un hijo : Redireccionar y Liberar, ALTURA
CAMBIA
– Si no,
• Bajar por el arbol, para buscar el menor de los mayores, intercambiar
• Eliminar ahora la clave izq de más a la derecha
• Subir por el mismo camino, actualizar factores
RECALCULANDO FACTORES
• Eliminación por el lado derecho, decrementa en 1 al fe
– Si era 0, ahora es –1, y su altura no cambia
– Si era 1, ahora es 0, altura cambia
– Si era –1, ahora es –2, ROTAR!!
• Dos posibles rotaciones II o ID
• Esto depende del siguiente derecho, si es <= 0 II, si no ID
• Si se escoge II y n1.fe == -1, altura no cambia
• Si es ID, altura cambia
• Eliminación por el lado izquierdo, aumenta en 1 al fe
– Si era 0, ahora es 1, y su altura no cambia
– Si era -1, ahora es 0, y su altura cambia
– Si era 1, ahora es 2, ROTAR!!
• Dos posibles rotaciones DI o DD
• Esto depende del siguiente derecho, si es >= 0: DD, si es negativo DI
• Si se escoge DD y n1.fe == 1, altura no cambia
• Si es DI, altura cambia
ELIMINAR: IMPLEMENTACION

boolean Eliminar(nodoAVL<E> raiz, E dato){ }else{


alturacambio = raiz.borrarMayorMenores(raiz.izq);
boolean alturacambio;
if(alturacambio)
if(raiz.estaVacio()) return false; return(ActualizarFEDer_Eliminar(raiz));
}
if(compare(raiz.data, dato)==0){
}
q = raiz; if(compare(dato, raiz.dato) < 0){
alturacambio = Eliminar(raiz.izq,dato)
if(raiz.der == null){
if(alturacambio)
raiz = q.izq; return(ActualizarFEIzq_Eliminarcion(raiz));
}else{
return(true);
alturacambio = Eliminar(raiz.der, dato)
} else if(raiz.izq == null){ if(alturacambio)
return(ActualizarFEDer_Eliminarcion(raiz));
raiz = q.der;
}
return(true); }
EJERCICIO
Crear un árbol AVL y un árbol ABB insertando las siguientes claves:
3, 2, 18, 5, 20, 90, 77, 40, 34, 12, 92

S-ar putea să vă placă și