Está en la página 1de 17

ÁRBOL AVL

Diego Márquez De La Hoz


Ingeniería de Sistemas
Descripción
 "Un algoritmo para la organización de la
información“.(Adelson-Velskii y Landis)
 Están siempre equilibrados. Es decir, para todos
los nodos, la altura de la rama izquierda no difiere
en más de una unidad de la altura de la rama
derecha o viceversa.
 La complejidad de una búsqueda se mantiene
siempre en orden de complejidad O(log n).
 Para conseguir la propiedad de equilibrio, la
inserción y el borrado de los nodos se ha de
realizar de una forma especial. Si no se preserva
esta propiedad, hay que realizar una serie de
rotaciones de los nodos.
Factor de equilibrio
 Cada nodo, además de la información que se
pretende almacenar, debe tener los dos
punteros a los árboles derecho e
izquierdo, igual que los árboles binarios de
búsqueda (ABB), y además 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 subárbol derecho - altura subárbol
izquierdo
OPERACIONES
Rotación simple a la derecha
 De un árbol de raíz (r) y
de hijos izq. (i) y
der.(d), se formara un
nuevo árbol cuya raíz
sea la raíz del hijo
izq., como hijo izq.
colocamos el hijo izq.
de i (i’) y como hijo der.
construimos un nuevo
árbol que tendrá como
raíz, la raíz del árbol
(r), el hijo der. de i (d’)
será el hijo izq. y el hijo
der. será el hijo
derecho del árbol (d).
Rotación simple a la
izquierda
 De un árbol de raíz (r) y
de hijos izq. (i) y der.
(d), se formara un
nuevo árbol cuya raíz
sea la raíz del hijo
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), el hijo izq.
de d será el hijo
derecho (i’) y el hijo izq.
será el hijo izq. del
árbol (i).
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.
 Proceso de inserción:
 1. buscar hasta encontrar la posición de inserción
 2. insertar el nuevo nodo con factor de equilibrio

 3. repasar el camino de búsqueda, verificando el


equilibrio de los nodos, y re-equilibrando si es
necesario
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, y la nueva raíz será M.

Borrado A, la nueva raíz es M.


Aplicamos la rotación a la derecha.

El árbol resultante ha perdido altura.


CÓDIGO EN JAVA
Class AvlNode
/**
*
* @author Diego
*/
public class AVLNode {

public Comparable dato; // el dato del nodo


public AVLNode izquierdo; // hijo izquierdo
public AVLNode derecho; // hijo derecho
public int height; // altura

// Constructors
public AVLNode(Comparable dato) {
this(dato, null, null);
}

public AVLNode(Comparable dato, AVLNode izq, AVLNode der) {


this.dato = dato;
this.izquierdo = izq;
this.derecho = der;
height = 0; // altura predeterminada
}
}
Class AvlTree
public class AVLTree { private static int max(int izquierdaHeight, int derechaHeight) {
private AVLNode root; return izquierdaHeight > derechaHeight ? izquierdaHeight : derechaHeight;
}
public void insert(Comparable x) {
root = insertar(x, root); private static AVLNode rotacionHijoIzquierdo(AVLNode t) {
} AVLNode aux2 = t.izquierdo;
t.izquierdo = aux2.derecho;
/* aux2.derecho = t;
* x es una instancia de una clase que implementa Comparable t.height = max(height(t.izquierdo), height(t.derecho)) + 1;
*/ aux2.height = max(height(aux2.izquierdo), t.height) + 1;
private AVLNode insertar(Comparable x, AVLNode t) { return aux2;
if (t == null) { }
t = new AVLNode(x, null, null);
} else if (x.compareTo(t.dato) < 0) { private static AVLNode rotacionHijoDerecho(AVLNode t) {
t.izquierdo = insertar(x, t.izquierdo); AVLNode aux2 = t.derecho;
if (height(t.izquierdo) - height(t.derecho) == 2) { t.derecho = aux2.izquierdo;
if (x.compareTo(t.izquierdo.dato) < 0) { aux2.izquierdo = t;
t = rotacionHijoIzquierdo(t); /* Caso 1 */ t.height = max(height(t.izquierdo), height(t.derecho)) + 1;
} else { aux2.height = max(height(aux2.derecho), t.height) + 1;
t = rotacionDobleHijoIzquierda(t); /* Caso 2 */ return aux2;
} }
}
} else if (x.compareTo(t.dato) > 0) {
t.derecho = insertar(x, t.derecho);
if (height(t.derecho) - height(t.izquierdo) == 2) {
if (x.compareTo(t.derecho.dato) > 0) {
t = rotacionHijoDerecho(t); /* Caso 4 */
} else {
t = rotacionDobleHijoDerecho(t); /* Caso 3 */
}
private static AVLNode rotacionDobleHijoIzquierda(AVLNode aux) {
aux.izquierdo = rotacionHijoDerecho(aux.izquierdo); private void imprimir(AVLNode nodo) {
return rotacionHijoIzquierdo(aux); if (nodo != null) {
} imprimir(nodo.derecho);
System.out.println("[" + nodo.dato + "]");
private static AVLNode rotacionDobleHijoDerecho(AVLNode aux) { imprimir(nodo.izquierdo);
aux.derecho = rotacionHijoIzquierdo(aux.derecho); }
return rotacionHijoDerecho(aux); }
}
public void imprimirPorAltura() {
private static int height(AVLNode t) { imprimirPorltura(root);
return t == null ? -1 : t.height; }
} /*
/* * Imprime cada nodo linea por linea. Recorriendo el arbol desde
* Imprime el arbol con el recorrido InOrden * el Nodo más a la derecha hasta el nodo más a la izquierda,
*/ * y dejando una identacion de varios espacios en blanco segun su
public void imprimir() { * altura en el arbol
imprimir(root); */
} private void imprimirPorltura(AVLNode nodo) {
if (nodo != null) {
imprimirPorltura(nodo.derecho);
System.out.println(replicate(" ", height(root) - height(nodo)) + "[" + nodo.dato + "]");
imprimirPorltura(nodo.izquierdo);
}
}
/* // Imprime el arbol por niveles. Comienza por la raiz.
* Metodo estatico auxiliar que dada una cadena a y un enterto cnt public void imprimirPorNiveles() {
* replica o concatena esa cadena a, cnt veces imprimirPorNiveles(root);
*/ }
private static String replicate(String a, int cnt) {
String x = new String(""); // Imprime el arbol por niveles.
private void imprimirPorNiveles(AVLNode nodo) {
for (int i = 0; i < cnt; i++) { // Mediante la altura calcula el total de nodos posibles del árbol
x = x + a; // Y crea una array cola con ese tamaño
} int max = 0;
return x; int nivel = calcularAltura();
}
for (; nivel >= 0; nivel--) {
/* max += Math.pow(2, nivel);
* Obtiene la altura del arbol AVL }
*/ max++; // Suma 1 para no utilizar la posicion 0 del array
public int calcularAltura() {
return calcularAltura(root); AVLNode cola[] = new AVLNode[max];
}
// Carga en la pos 1 el nodo raiz
private int calcularAltura(AVLNode actual) { cola[1] = nodo;
if (actual == null) { int x = 1;
return -1;
} else {
return 1 + Math.max(calcularAltura(actual.izquierdo), calcularAltura(actual.derecho));
}
}
// Carga los demas elementos del arbol,
// 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 System.out.print("[" + cola[i].dato + "]");
// x aumenta 1, que son los nodos raiz - padre cont++;
for (int i = 2; i < max; i += 2, x++) { }
if (cola[x] == null) { if (ultimaPosicion == i && cantidad == Math.pow(2, --nivel)) {
cola[i] = null; if (cantidad == 1) {
cola[i + 1] = null; System.out.print(" Cantidad de nodos: " + cont + " (raiz)");
} else { } else {
cola[i] = cola[x].izquierdo; System.out.print(" Cantidad de nodos: " + cont);
cola[i + 1] = cola[x].derecho; }
} cont = 0;
} cantidad *= 2;
nivel = 0; ultimaPosicion += (int) Math.pow(2, ++nivel);
int cont = 0; // contador para cada nivel }
int cantidad = 1; // cantidad de nodos por nivel }
int ultimaPosicion = 1; // ultimaPosicion del nodo en la cola de cada nivel }
}
// Cuando i es = a 2^nivel hay cambio de nivel
// 2 ^ 0 = 1 que es el nodo raiz
for (int i = 1; i < max; i++) {
if (i == Math.pow(2, nivel)) {
// Nodo raiz tiene nivel 1, por eso (nivel + 1)
System.out.print("\n Nivel " + (nivel) + ": ");
nivel++;
}
Class EjecutableAvlTree
/** arbolAVL.insert(elemento1);
* arbolAVL.insert(elemento2);
* @author Diego arbolAVL.insert(elemento3);
*/ arbolAVL.insert(elemento4);
public class EjecutableAVLTree { arbolAVL.insert(elemento5);
arbolAVL.insert(elemento6);
/** arbolAVL.insert(elemento7);
* @param args the command line arguments arbolAVL.insert(elemento8);
*/ arbolAVL.insert(elemento9);
public static void main(String[] args) { arbolAVL.insert(elemento10);
// TODO code application logic here
AVLTree arbolAVL = new AVLTree(); arbolAVL.imprimirPorNiveles();

Integer elemento1 = new Integer("1"); int altura = arbolAVL.calcularAltura() + 1;


Integer elemento2 = new Integer("2");
Integer elemento3 = new Integer("3"); System.out.println("\n");
Integer elemento4 = new Integer("4"); System.out.println(altura + " altura del arbol");
Integer elemento5 = new Integer("5"); System.out.println("\n");
Integer elemento6 = new Integer("6");
Integer elemento7 = new Integer("7"); arbolAVL.imprimirPorAltura();
Integer elemento8 = new Integer("15");
Integer elemento9 = new Integer("14");
Integer elemento10 = new Integer("13");

}
}

También podría gustarte