arboles avl con codigo en java
description
Transcript of arboles avl con codigo en java
![Page 1: arboles avl con codigo en java](https://reader031.fdocuments.es/reader031/viewer/2022012321/559e01fe1a28ab2f6a8b4636/html5/thumbnails/1.jpg)
ÁRBOL AVLDiego Márquez De La Hoz
Ingeniería de Sistemas
![Page 2: arboles avl con codigo en java](https://reader031.fdocuments.es/reader031/viewer/2022012321/559e01fe1a28ab2f6a8b4636/html5/thumbnails/2.jpg)
Descripción
"Un algoritmo para la organización de lainformación“.(Adelson-Velskii y Landis)
Están siempre equilibrados. Es decir, para todoslos nodos, la altura de la rama izquierda no difiereen más de una unidad de la altura de la ramaderecha o viceversa.
La complejidad de una búsqueda se mantienesiempre en orden de complejidad O(log n).
Para conseguir la propiedad de equilibrio, lainserción y el borrado de los nodos se ha derealizar de una forma especial. Si no se preservaesta propiedad, hay que realizar una serie derotaciones de los nodos.
![Page 3: arboles avl con codigo en java](https://reader031.fdocuments.es/reader031/viewer/2022012321/559e01fe1a28ab2f6a8b4636/html5/thumbnails/3.jpg)
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
![Page 4: arboles avl con codigo en java](https://reader031.fdocuments.es/reader031/viewer/2022012321/559e01fe1a28ab2f6a8b4636/html5/thumbnails/4.jpg)
OPERACIONES
![Page 5: arboles avl con codigo en java](https://reader031.fdocuments.es/reader031/viewer/2022012321/559e01fe1a28ab2f6a8b4636/html5/thumbnails/5.jpg)
Rotación simple a la derecha
De un árbol de raíz (r) yde hijos izq. (i) yder.(d), se formara unnuevo árbol cuya raízsea la raíz del hijoizq., como hijo izq.colocamos el hijo izq.de i (i’) y como hijo der.construimos un nuevoárbol que tendrá comoraíz, la raíz del árbol(r), el hijo der. de i (d’)será el hijo izq. y el hijoder. será el hijoderecho del árbol (d).
![Page 6: arboles avl con codigo en java](https://reader031.fdocuments.es/reader031/viewer/2022012321/559e01fe1a28ab2f6a8b4636/html5/thumbnails/6.jpg)
Rotación simple a la
izquierda De un árbol de raíz (r) y
de hijos izq. (i) y der.(d), se formara unnuevo árbol cuya raízsea la raíz del hijoder., como hijo der.colocamos el hijo der.de d (d’) y como hijoizquierdo construimosun nuevo árbol quetendrá como raíz la raízdel árbol (r), el hijo izq.de d será el hijoderecho (i’) y el hijo izq.será el hijo izq. delárbol (i).
![Page 7: arboles avl con codigo en java](https://reader031.fdocuments.es/reader031/viewer/2022012321/559e01fe1a28ab2f6a8b4636/html5/thumbnails/7.jpg)
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
![Page 8: arboles avl con codigo en java](https://reader031.fdocuments.es/reader031/viewer/2022012321/559e01fe1a28ab2f6a8b4636/html5/thumbnails/8.jpg)
![Page 9: arboles avl con codigo en java](https://reader031.fdocuments.es/reader031/viewer/2022012321/559e01fe1a28ab2f6a8b4636/html5/thumbnails/9.jpg)
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.
![Page 10: arboles avl con codigo en java](https://reader031.fdocuments.es/reader031/viewer/2022012321/559e01fe1a28ab2f6a8b4636/html5/thumbnails/10.jpg)
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.
![Page 11: arboles avl con codigo en java](https://reader031.fdocuments.es/reader031/viewer/2022012321/559e01fe1a28ab2f6a8b4636/html5/thumbnails/11.jpg)
CÓDIGO EN JAVA
![Page 12: arboles avl con codigo en java](https://reader031.fdocuments.es/reader031/viewer/2022012321/559e01fe1a28ab2f6a8b4636/html5/thumbnails/12.jpg)
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
}
}
![Page 13: arboles avl con codigo en java](https://reader031.fdocuments.es/reader031/viewer/2022012321/559e01fe1a28ab2f6a8b4636/html5/thumbnails/13.jpg)
Class AvlTree
public class AVLTree {
private AVLNode root;
public void insert(Comparable x) {
root = insertar(x, root);
}
/*
* x es una instancia de una clase que implementa Comparable
*/
private AVLNode insertar(Comparable x, AVLNode t) {
if (t == null) {
t = new AVLNode(x, null, null);
} else if (x.compareTo(t.dato) < 0) {
t.izquierdo = insertar(x, t.izquierdo);
if (height(t.izquierdo) - height(t.derecho) == 2) {
if (x.compareTo(t.izquierdo.dato) < 0) {
t = rotacionHijoIzquierdo(t); /* Caso 1 */
} else {
t = rotacionDobleHijoIzquierda(t); /* Caso 2 */
}
}
} 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 int max(int izquierdaHeight, int derechaHeight) {
return izquierdaHeight > derechaHeight ? izquierdaHeight : derechaHeight;
}
private static AVLNode rotacionHijoIzquierdo(AVLNode t) {
AVLNode aux2 = t.izquierdo;
t.izquierdo = aux2.derecho;
aux2.derecho = t;
t.height = max(height(t.izquierdo), height(t.derecho)) + 1;
aux2.height = max(height(aux2.izquierdo), t.height) + 1;
return aux2;
}
private static AVLNode rotacionHijoDerecho(AVLNode t) {
AVLNode aux2 = t.derecho;
t.derecho = aux2.izquierdo;
aux2.izquierdo = t;
t.height = max(height(t.izquierdo), height(t.derecho)) + 1;
aux2.height = max(height(aux2.derecho), t.height) + 1;
return aux2;
}
![Page 14: arboles avl con codigo en java](https://reader031.fdocuments.es/reader031/viewer/2022012321/559e01fe1a28ab2f6a8b4636/html5/thumbnails/14.jpg)
private static AVLNode rotacionDobleHijoIzquierda(AVLNode aux) {
aux.izquierdo = rotacionHijoDerecho(aux.izquierdo);
return rotacionHijoIzquierdo(aux);
}
private static AVLNode rotacionDobleHijoDerecho(AVLNode aux) {
aux.derecho = rotacionHijoIzquierdo(aux.derecho);
return rotacionHijoDerecho(aux);
}
private static int height(AVLNode t) {
return t == null ? -1 : t.height;
}
/*
* Imprime el arbol con el recorrido InOrden
*/
public void imprimir() {
imprimir(root);
}
private void imprimir(AVLNode nodo) {
if (nodo != null) {
imprimir(nodo.derecho);
System.out.println("[" + nodo.dato + "]");
imprimir(nodo.izquierdo);
}
}
public void imprimirPorAltura() {
imprimirPorltura(root);
}
/*
* Imprime cada nodo linea por linea. Recorriendo el arbol desde
* 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
* altura en el arbol
*/
private void imprimirPorltura(AVLNode nodo) {
if (nodo != null) {
imprimirPorltura(nodo.derecho);
System.out.println(replicate(" ", height(root) - height(nodo)) + "[" + nodo.dato + "]");
imprimirPorltura(nodo.izquierdo);
}
}
![Page 15: arboles avl con codigo en java](https://reader031.fdocuments.es/reader031/viewer/2022012321/559e01fe1a28ab2f6a8b4636/html5/thumbnails/15.jpg)
/*
* Metodo estatico auxiliar que dada una cadena a y un enterto cnt
* replica o concatena esa cadena a, cnt veces
*/
private static String replicate(String a, int cnt) {
String x = new String("");
for (int i = 0; i < cnt; i++) {
x = x + a;
}
return x;
}
/*
* Obtiene la altura del arbol AVL
*/
public int calcularAltura() {
return calcularAltura(root);
}
private int calcularAltura(AVLNode actual) {
if (actual == null) {
return -1;
} else {
return 1 + Math.max(calcularAltura(actual.izquierdo), calcularAltura(actual.derecho));
}
}
// Imprime el arbol por niveles. Comienza por la raiz.
public void imprimirPorNiveles() {
imprimirPorNiveles(root);
}
// Imprime el arbol por niveles.
private void imprimirPorNiveles(AVLNode nodo) {
// Mediante la altura calcula el total de nodos posibles del árbol
// Y crea una array cola con ese tamaño
int max = 0;
int nivel = calcularAltura();
for (; nivel >= 0; nivel--) {
max += Math.pow(2, nivel);
}
max++; // Suma 1 para no utilizar la posicion 0 del array
AVLNode cola[] = new AVLNode[max];
// Carga en la pos 1 el nodo raiz
cola[1] = nodo;
int x = 1;
![Page 16: arboles avl con codigo en java](https://reader031.fdocuments.es/reader031/viewer/2022012321/559e01fe1a28ab2f6a8b4636/html5/thumbnails/16.jpg)
// Carga los demas elementos del arbol,
// Carga null en izq y der si el nodo es null
// i aumenta de a 2 por q carga en izq y der los hijos
// x aumenta 1, que son los nodos raiz - padre
for (int i = 2; i < max; i += 2, x++) {
if (cola[x] == null) {
cola[i] = null;
cola[i + 1] = null;
} else {
cola[i] = cola[x].izquierdo;
cola[i + 1] = cola[x].derecho;
}
}
nivel = 0;
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++;
}
if (cola[i] != null) {
System.out.print("[" + cola[i].dato + "]");
cont++;
}
if (ultimaPosicion == i && cantidad == Math.pow(2, --nivel)) {
if (cantidad == 1) {
System.out.print(" Cantidad de nodos: " + cont + " (raiz)");
} else {
System.out.print(" Cantidad de nodos: " + cont);
}
cont = 0;
cantidad *= 2;
ultimaPosicion += (int) Math.pow(2, ++nivel);
}
}
}
}
![Page 17: arboles avl con codigo en java](https://reader031.fdocuments.es/reader031/viewer/2022012321/559e01fe1a28ab2f6a8b4636/html5/thumbnails/17.jpg)
Class EjecutableAvlTree
/**
*
* @author Diego
*/
public class EjecutableAVLTree {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
AVLTree arbolAVL = new AVLTree();
Integer elemento1 = new Integer("1");
Integer elemento2 = new Integer("2");
Integer elemento3 = new Integer("3");
Integer elemento4 = new Integer("4");
Integer elemento5 = new Integer("5");
Integer elemento6 = new Integer("6");
Integer elemento7 = new Integer("7");
Integer elemento8 = new Integer("15");
Integer elemento9 = new Integer("14");
Integer elemento10 = new Integer("13");
arbolAVL.insert(elemento1);
arbolAVL.insert(elemento2);
arbolAVL.insert(elemento3);
arbolAVL.insert(elemento4);
arbolAVL.insert(elemento5);
arbolAVL.insert(elemento6);
arbolAVL.insert(elemento7);
arbolAVL.insert(elemento8);
arbolAVL.insert(elemento9);
arbolAVL.insert(elemento10);
arbolAVL.imprimirPorNiveles();
int altura = arbolAVL.calcularAltura() + 1;
System.out.println("\n");
System.out.println(altura + " altura del arbol");
System.out.println("\n");
arbolAVL.imprimirPorAltura();
}
}