You are on page 1of 8

Descripcin

Un ejemplo de rbol binario no equilibrado (no es AVL)

Un ejemplo de rbol binario equilibrado (si es AVL) El rbol AVL toma su nombre de las iniciales de los apellidos de sus inventores, Adelson-Velskii y Landis. Lo dieron a conocer en la publicacin de un artculo en 1962: "An algorithm for the organization of information" ("Un algoritmo para la organizacin de la informacin"). Los rboles AVL estn siempre equilibrados de tal modo que para todos los nodos, la altura de la rama izquierda no difiere en ms de una unidad de la altura de la rama derecha. Gracias a esta forma de equilibrio (o balanceo), la complejidad de una bsqueda en uno de estos rboles se mantiene siempre en orden de complejidad O(log n). El factor de equilibrio puede ser almacenado directamente en cada nodo o ser computado a partir de las alturas de los subrboles. Para conseguir esta propiedad de equilibrio, la insercin y el borrado de los nodos se ha de realizar de una forma especial. Si al realizar una operacin de insercin o borrado se rompe la condicin de equilibrio, hay que realizar una serie de rotaciones de los nodos. Los rboles AVL ms profundos son los rboles de Fibonacci. Definicin formal Definicin de la altura de un rbol Sea T un rbol binario de bsqueda y sean Ti y Td sus subrboles, su altura H(T), es:

y y

0 si el rbol T contiene solo la raz 1 + max(H(Ti),H(Td)) si contiene ms nodos

Definicin de rbol AVL

y y

Un rbol vaco es un rbol AVL Si T es un rbol no vaco y Ti y Td sus subrboles, entonces T es AVL si y solo si:

y y y

Ti es AVL Td es AVL | H(Ti) H(Td) | < = 1

Factor de equilibrio Cada nodo, adems de la informacin que se pretende almacenar, debe tener los dos punteros a los rboles derecho e izquierdo, igual que los rboles binarios de bsqueda (ABB), y adems el dato que controla el factor de equilibrio. El factor de equilibrio es la diferencia entre las alturas del rbol derecho y el izquierdo: FE = altura subrbol derecho - altura subrbol izquierdo; Por definicin, para un rbol AVL, este valor debe ser -1, 0 1. Si el factor de equilibrio de un nodo es: 0 -> el nodo est equilibrado y sus subrboles tienen exactamente la misma altura. 1 -> el nodo est equilibrado y su subrbol derecho es un nivel ms alto.

-1 -> el nodo est equilibrado y su subrbol izquierdo es un nivel ms alto. Si el factor de equilibrio Fe 2 o Fe -2 es necesario reequilibrar. Operaciones Las operaciones bsicas de un rbol AVL implican generalmente el realizar los mismos algoritmos que seran realizados en un rbol binario de bsqueda desequilibrado, pero precedido o seguido por una o ms de las llamadas "rotaciones AVL". Rotaciones El reequilibrado se produce de abajo hacia arriba sobre los nodos en los que se produce el desequilibrio. Pueden darse dos casos: rotacin simple o rotacin doble; a su vez ambos casos pueden ser hacia la derecha o hacia la izquierda.

ROTACIN SIMPLE A LA DERECHA. De un rbol de raz (r) y de hijos izquierdo (i) y derecho (d), lo que haremos ser formar un nuevo rbol cuya raz sea la raz del hijo izquierdo, como hijo izquierdo colocamos el hijo izquierdo de i (nuestro i ) y como hijo derecho construimos un nuevo rbol que tendr como raz, la raz del rbol (r), el hijo derecho de i (d ) ser el hijo izquierdo y el hijo derecho ser el hijo derecho del rbol (d).

op rotDer: AVL{X} -> [AVL{X}] . eq rotDer(arbolBin(R1, arbolBin(R2, I2, D2), D1)) == arbolBin(R2, I2, arbolBin(R1, D2, D)) . ROTACIN SIMPLE A LA IZQUIERDA. De un rbol de raz (r) y de hijos izquierdo (i) y derecho (d), consiste en formar un nuevo rbol cuya raz sea la raz del hijo derecho, como hijo derecho colocamos el hijo derecho de d (nuestro d ) y como hijo izquierdo construimos un nuevo rbol que tendr como raz la raz del rbol (r), el hijo izquierdo de d ser el hijo derecho (i ) y el hijo izquierdo ser el hijo izquierdo del rbol (i). Precondicin : Tiene que tener hijo derecho no vaco.

op rotIzq: AVL{X} -> [AVL{X}] . eq rotIzq(arbolBin(R1, I, arbolBin(R2, I2, D2))) == arbolBin(R2, arbolBin(R1, I, I2), D2) .

Si la insercin se produce en el hijo derecho del hijo izquierdo del nodo desequilibrado (o viceversa) hay que realizar una doble rotacin. ROTACIN DOBLE A LA DERECHA.

ROTACIN DOBLE A LA IZQUIERDA.

[editar] Insercin La insercin en un rbol de AVL puede ser realizada insertando el valor dado en el rbol como si fuera un rbol de bsqueda binario desequilibrado y despus retrocediendo hacia la raz, rotando sobre cualquier nodo que pueda haberse desequilibrado durante la insercin. Proceso de insercin: 1.buscar hasta encontrar la posicin de insercin o modificacin (proceso idntico a insercin en rbol binario de bsqueda) 2.insertar el nuevo nodo con factor de equilibrio equilibrado 3.desandar el camino de bsqueda, verificando el equilibrio de los nodos, y re-equilibrando si es necesario

Debido a que las rotaciones son una operacin que tienen complejidad constante y a que la altura esta limitada a O (log(n)), el tiempo de ejecucin para la insercin es del orden O (log(n)). op insertar: X$Elt AVL{X} -> AVLNV{X} . eq insertar(R, crear) == arbolBin(R, crear, crear) . ceq insertar(R1, arbolBin(R2, I, D)) == if (R1==R2) then arbolBin(R2, I, D) elseif (R1<R2) then if ( (altura(insertar(R1,I)) altura(D)) < 2) then arbolBin(R2, insertar(R1, I), D) else ***hay que reequilibrar if (R1 < raiz(I)) then rotarDer(arbolBin(R2, insertar(R1, I), D)) else rotarDer(arbolBin(R2, rotarIzq(insertar(R1, I)), D)) fi . fi . else if ( (altura(insertar(R1,I)) altura(D)) < 2) then arbolBin(R2, insertar(R1, I), D) else *** hay que reequilibrar if (R1 > raiz(D)) then rotarIzq(arbolBin(R, I, insertar(R1, D))) else rotatIzq(arbolBin(R, I, rotarDer(insertar(R1, D)))) fi . fi . fi . [editar] Extraccin El procedimiento de borrado es el mismo que en el caso de rbol binario de bsqueda.La diferencia se encuentra en el proceso de reequilibrado posterior. El problema de la extraccin puede resolverse en O (log n) pasos. Una extraccin trae consigo una disminucin de la altura de la rama donde se extrajo y tendr como efecto un cambio en el factor de equilibrio del nodo padre de la rama en cuestin, pudiendo necesitarse una rotacin. Esta disminucin de la altura y la correccin de los factores de equilibrio con sus posibles rotaciones asociadas pueden propagarse hasta la raz.

Borrar A, y la nueva raz ser M.

Borrado A, la nueva raz es M. Aplicamos la rotacin a la derecha.

El rbol resultante ha perdido altura. En borrado pueden ser necesarias varias operaciones de restauracin del equilibrio, y hay que seguir comprobando hasta llegar a la raz.

op eliminar: X$Elt AVL{X} -> AVL{X} . eq eliminar(R, crear) == crear . ceq eliminar(R1, arbolBin(R2, I, D)) == if (R1 == R2) then if esVacio(I) then D elseif esVacio(D) then I else if (altura(I) - altura(eliminar(min(D),D)) < 2) then arbolBin(min(D), I, eliminar(min(D), D)) ***tenemos que reequilibrar elseif (altura(hijoIzq(I) >= altura(hijoDer(I)))) then rotDer(arbolBin(min(D), I, eliminar(min(D),D))) else rotDer(arbolBin(min(D), rotIzq(I), eliminar(min(D),D))) [editar] Bsqueda public class Nodo { int numMat; Nodo izqda, drcha; public Nodo(int mat){ numMat = mat; izqda = drcha = null; } public void re_enorden(){ if(izqda != null) izqda.re_enorden(); System.out.println("Matricula: " +numMat); if(drcha != null) drcha.re_enorden(); }

} public class ABB { private Nodo raiz; public ABB(){ raiz = null; } public void insertar(int nuevoM){ if(raiz==null){ raiz = new Nodo(nuevoM); } else{ insertar(raiz,nuevoM); } } private void insertar(Nodo rz, int nm){ if (rz == null) rz = new Nodo(nm); else if(nm < rz.numMat) insertar(rz.izqda,nm); else if(nm > rz.numMat) insertar(rz.drcha,nm); else System.out.println("Numero Duplicados"); } public void visualizar(){ if(raiz!=null) raiz.re_enorden(); } } public class Ejecutar { public static void main(String []args){ ABB arbol = new ABB(); arbol.insertar(6); arbol.insertar(3); arbol.insertar(7); arbol.visualizar(); } } Ejemplo de TAD AVL #include <stdio.h> typedef struct AVL{ int dato, FB; // FB es la altura del subarbol izquierdo menos la altura del subarbol derecho AVL *izq, *der; bool borrado; } AVL; void rotarLL(AVL* &A){ //precond: el arbol necesita una rotacion LL AVL* aux = A->izq->der; A->izq->der = A; A->izq->FB = 0; AVL* aux2 = A->izq; A->izq = aux; A->FB = 0; A = aux2; } void rotarRR(AVL* &A){ //precond: el arbol necesita una rotacion RR AVL* aux = A->der->izq; A->der->izq = A; A->der->FB = 0; AVL* aux2 = A->der; A->der = aux; A->FB = 0; A = aux2; } void rotarLRalter(AVL* &A){ //precond: el arbol necesita una rotacion LR rotarRR(A->izq); rotarLL(A); }

void rotarRLalter(AVL* &A){ //precond: el arbol necesita una rotacion RL rotarLL(A->der); rotarRR(A); } AVL* Crear(){ return NULL; } void Insert(int n, bool &aumento, AVL* &A){ if (A == NULL){ A = new AVL; A->dato = n; A->FB = 0; A->izq = NULL; A->der = NULL; aumento = true; A->borrado = false; }else{ if (n < A->dato){ Insert(n, aumento, A->izq); if (aumento){ switch (A->FB){ case -1:{ A->FB = 0; aumento = false; break; } case 0:{ A->FB = 1; aumento = true; break; } case 1:{ if (A->izq->FB == 1){ // Si es 1 necesita una rotacion LL si es -1 necesita una rotacion LR rotarLL(A); }else{ rotarLRalter(A); } aumento = false; break; } } } }else{ Insert(n, aumento, A->der); if (aumento){ switch (A->FB){ case -1:{ if (A->der->FB == 1){ // Si es 1 necesita una rotacion RL si es -1 necesita una rotacion RR rotarRLalter(A); }else{ rotarRR(A); } aumento = false; break; } case 0:{ A->FB = -1; aumento = true; break; } case 1:{ A->FB = 0; aumento = false; break; } } } } } } void Insertar(AVL* &A, int n){ bool aumento;

Insert(n, aumento, A); } bool EsVacio(AVL* A){ return A == NULL; } bool Pertenece(AVL* A, int n){ if (A == NULL){ return false; }else{ if (A->dato == n){ if (A->borrado){ return false; }else{ return true; } }else if (n < A->dato){ return Pertenece(A->izq, n); }else{ return Pertenece(A->der, n); } } } void Borrar(AVL* &A, int n){ if (A->dato == n){ A->borrado = true; }else if (n < A->dato){ Borrar(A->izq, n); }else{ Borrar(A->der, n); } }

You might also like