You are on page 1of 17

ÁRBOL AVL

Diego Márquez De La Hoz
Ingeniería de Sistemas

la altura de la rama izquierda no difiere en más de una unidad de la altura de la rama derecha o viceversa. para todos los nodos. hay que realizar una serie de rotaciones de los nodos. Es decir.  Para conseguir la propiedad de equilibrio.  La complejidad de una búsqueda se mantiene siempre en orden de complejidad O(log n).(Adelson-Velskii y Landis)  Están siempre equilibrados. Si no se preserva esta propiedad. la inserción y el borrado de los nodos se ha de realizar de una forma especial. .Descripción  "Un algoritmo para la organización de la información“.

debe tener los dos punteros a los árboles derecho e izquierdo. igual que los árboles binarios de búsqueda (ABB).altura subárbol izquierdo .  El factor de equilibrio es la diferencia entre las alturas del árbol derecho y el izquierdo:  FE = altura subárbol derecho . además de la información que se pretende almacenar. y además el dato que controla el factor de equilibrio.Factor de equilibrio  Cada nodo.

OPERACIONES .

se formara un nuevo árbol cuya raíz sea la raíz del hijo izq.(d). será el hijo derecho del árbol (d). el hijo der. y el hijo der. colocamos el hijo izq. de i (d’) será el hijo izq. (i) y der. construimos un nuevo árbol que tendrá como raíz. . de i (i’) y como hijo der.. como hijo izq. la raíz del árbol (r).Rotación simple a la derecha  De un árbol de raíz (r) y de hijos izq.

. (i) y der. como hijo der. colocamos el hijo der. de d (d’) y como hijo izquierdo construimos un nuevo árbol que tendrá como raíz la raíz del árbol (r). se formara un nuevo árbol cuya raíz sea la raíz del hijo der. de d será el hijo derecho (i’) y el hijo izq. será el hijo izq. (d).Rotación simple a la izquierda  De un árbol de raíz (r) y de hijos izq. el hijo izq. . del árbol (i).

repasar el camino de búsqueda. buscar hasta encontrar la posición de inserción  2.Inserción  Puede ser realizada insertando el valor dado en el árbol como si fuera un árbol de búsqueda binario desequilibrado y después retrocediendo hacia la raíz. rotando sobre cualquier nodo que pueda haberse desequilibrado durante la inserción. y re-equilibrando si es necesario .  Proceso de inserción:  1. verificando el equilibrio de los nodos. insertar el nuevo nodo con factor de equilibrio  3.

.

.Extracción  Una extracción trae consigo una disminución 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 cuestión. pudiendo necesitarse una rotación.

Borrar A. Aplicamos la rotación a la derecha. . y la nueva raíz será M. la nueva raíz es M. Borrado A. El árbol resultante ha perdido altura.

CÓDIGO EN JAVA .

AVLNode der) { this. null. // hijo izquierdo public AVLNode derecho. // el dato del nodo public AVLNode izquierdo. height = 0. // altura // Constructors public AVLNode(Comparable dato) { this(dato. AVLNode izq. } public AVLNode(Comparable dato.dato = dato. this.Class AvlNode /** * * @author Diego */ public class AVLNode { public Comparable dato. null). this. // hijo derecho public int height.derecho = der. // altura predeterminada } } .izquierdo = izq.

t. } } /* * x es una instancia de una clase que implementa Comparable private static AVLNode rotacionHijoIzquierdo(AVLNode t) { */ private AVLNode insertar(Comparable x.height) + 1.height = max(height(t.dato) > 0) { t = rotacionHijoDerecho(t). t.derecho).dato) > 0) { t.derecho)) + 1. height(t. AVLNode t) { AVLNode aux2 = t.compareTo(t.derecho. root).izquierdo = t. t = rotacionDobleHijoDerecho(t). t.derecho = insertar(x.height = max(height(t.izquierdo = aux2. } } else aux2.compareTo(t. no hago nada return aux2.Class AvlTree public class AVLTree { private AVLNode root. t. } } .izquierdo. t.compareTo(t. private static int max(int izquierdaHeight. /* Caso 2 */ } } } } else if (x. int derechaHeight) { return izquierdaHeight > derechaHeight ? public void insert(Comparable x) { izquierdaHeight : derechaHeight.derecho).izquierdo.izquierdo).izquierdo) == 2) { AVLNode aux2 = t.derecho)) + 1. return t.izquierdo). t = rotacionDobleHijoIzquierda(t). height(t.izquierdo.izquierdo). root = insertar(x.height) + 1. null).derecho) == 2) { t.height = max(height(aux2.izquierdo = insertar(x.dato) < 0) { aux2. /* Caso 3 */ } t.derecho)) + 1. /* Caso 4 */ t. } else if (x. t. t = new AVLNode(x.height = max(height(t.derecho.izquierdo). // Duplicado. .height = max(height(aux2. height(t.derecho) . if (x.izquierdo).compareTo(t.height(t. } else { aux2. null. if (height(t. /* Caso 1 */ } else { return aux2. private static AVLNode rotacionHijoDerecho(AVLNode t) { if (height(t. if (x.izquierdo) .height(t. t = rotacionHijoIzquierdo(t).derecho. if (t == null) { t.dato) < 0) { aux2.derecho = aux2.derecho = t.

derecho).izquierdo).println("[" + nodo.out. /* } * Imprime cada nodo linea por linea. */ } private void imprimirPorltura(AVLNode nodo) { /* if (nodo != null) { * Imprime el arbol con el recorrido InOrden imprimirPorltura(nodo. private static AVLNode rotacionDobleHijoIzquierda(AVLNode aux) { private void imprimir(AVLNode nodo) { aux. } } } private static AVLNode rotacionDobleHijoDerecho(AVLNode aux) { public void imprimirPorAltura() { aux.height.derecho).println(replicate(" ". imprimir(nodo.dato + "]").derecho = imprimirPorltura(root). imprimir(nodo. * y dejando una identacion de varios espacios en blanco segun su private static int height(AVLNode t) { * altura en el arbol return t == null ? -1 : t. Recorriendo el arbol desde * el Nodo más a la derecha hasta el nodo más a la izquierda.derecho).izquierdo). imprimir(root). } return rotacionHijoDerecho(aux).dato + "]"). return rotacionHijoIzquierdo(aux). height(root) .height(nodo)) + "[" + nodo.out. rotacionHijoIzquierdo(aux. */ System. System. public void imprimir() { imprimirPorltura(nodo.izquierdo = if (nodo != null) { rotacionHijoDerecho(aux.izquierdo). } } } .

derecho)).pow(2. * Obtiene la altura del arbol AVL */ public int calcularAltura() { for (. } else { return 1 + Math. for (int i = 0. * Metodo estatico auxiliar que dada una cadena a y un enterto cnt public void imprimirPorNiveles() { * replica o concatena esa cadena a. /* int nivel = calcularAltura(). max += Math. calcularAltura(actual.max(calcularAltura(actual. Comienza por la raiz. i++) { private void imprimirPorNiveles(AVLNode nodo) { x = x + a. // Imprime el arbol por niveles. nivel >= 0.izquierdo). // Carga en la pos 1 el nodo raiz } cola[1] = nodo. int cnt) { } String x = new String(""). cnt veces imprimirPorNiveles(root). } int x = 1. } // Mediante la altura calcula el total de nodos posibles del return x. árbol } // Y crea una array cola con ese tamaño int max = 0. } } max++. nivel--) { return calcularAltura(root). AVLNode cola[] = new AVLNode[max]. . */ private static String replicate(String a./* // Imprime el arbol por niveles. nivel). // Suma 1 para no utilizar la posicion 0 del array private int calcularAltura(AVLNode actual) { if (actual == null) { return -1. i < cnt.

print(" Cantidad de nodos: " + int cantidad = 1. for (int i = 1. System. // cantidad de nodos por nivel cont). nivel)) { } // Nodo raiz tiene nivel 1. i += 2. por eso (nivel + 1) } System.out.out. // Carga los demas elementos del arbol. ++nivel). // 2 ^ 0 = 1 que es el nodo raiz ultimaPosicion += (int) Math. for (int i = 2. x++) { cont++. i++) { if (i == Math. if (cantidad == 1) { cola[i + 1] = cola[x]. int ultimaPosicion = 1.derecho. } nivel = 0. i < max. if (ultimaPosicion == i && cantidad == } else { Math. // ultimaPosicion del nodo } en la cola de cada nivel cont = 0.izquierdo. if (cola[x] == null) { } cola[i] = null. cola[i + 1] = null. } else { int cont = 0.padre System. --nivel)) { cola[i] = cola[x].out. // Cuando i es = a 2^nivel hay cambio de nivel cantidad *= 2.print(" Cantidad de nodos: " + } cont + " (raiz)").dato + "]"). // contador para cada nivel System. } } .pow(2. i < max. } nivel++.print("\n Nivel " + (nivel) + ": ").pow(2. // Carga null en izq y der si el nodo es null if (cola[i] != null) { // i aumenta de a 2 por q carga en izq y der los hijos // x aumenta 1.pow(2.out.print("[" + cola[i]. que son los nodos raiz .

insert(elemento1). System. * @author Diego arbolAVL.insert(elemento2).calcularAltura() + 1. Integer elemento3 = new Integer("3"). */ arbolAVL.imprimirPorNiveles(). * @param args the command line arguments arbolAVL. arbolAVL. int altura = arbolAVL.out.insert(elemento9).insert(elemento8).insert(elemento6).out. AVLTree arbolAVL = new AVLTree().insert(elemento10).insert(elemento3).println("\n"). */ arbolAVL. Integer elemento6 = new Integer("6"). Integer elemento4 = new Integer("4"). System. Integer elemento8 = new Integer("15").Class EjecutableAvlTree /** arbolAVL. public class EjecutableAVLTree { arbolAVL. Integer elemento2 = new Integer("2").imprimirPorAltura(). Integer elemento7 = new Integer("7"). } . arbolAVL. arbolAVL. * arbolAVL.insert(elemento4). /** arbolAVL.out.insert(elemento5). Integer elemento1 = new Integer("1").insert(elemento7).println("\n"). } Integer elemento10 = new Integer("13"). System.println(altura + " altura del arbol"). public static void main(String[] args) { // TODO code application logic here arbolAVL. Integer elemento5 = new Integer("5"). Integer elemento9 = new Integer("14").