Cap_4(tda_AVL)_2008

Post on 27-Sep-2015

2 views 0 download

description

Estructuras de datos ,Arboles AVL

Transcript of Cap_4(tda_AVL)_2008

Arboles AVL

Diseo y Anlisis de Algoritmos con Java Dr.Eric Jeltsch F.

Arboles AVL

Objetivo: Lo substancial de este informe se centra en poder reconocer los rboles AVL, por otra parte superar el problema generado por la insercin en los rboles de Bsqueda Binaria que podan degenerar en una lista proporcional a los datos ingresados y por otra reforzar los conceptos adquiridos en Estructuras de Datos, como al mismo tiempo practicar su implementacin con la ayuda del lenguaje de programacin Java.

Introduccin: Una de las primeras estructuras de datos de rboles de bsqueda equilibrados que consideraremos son los rboles AVL ( que llevan el nombre de sus autores Adelson-Velskii-Landis), existen otros tipos de estructuras similares, tales como los rboles Red-Black y otros. En este informe se presenta la definicin de los rboles AVL, con ejemplos. Se hace una estimacin del nmero de nodos en el peor rbol AVL de altura h. Se revisa, en particular, el mtodo de Insertar, con ejemplos. Adems se muestra la implementacin en Java de cada uno de los componentes, tales como Nodo, Arbol AVL y las Rotaciones, como el medio para lograr la implementacin de Insercin en los rboles AVL. Finalmente, se hace una simulacin de la implementacin y se interpreta la salida, junto con mencionar algunas mejoras, u otras especificaciones que se le podran realizar, como por ejemplo considerar que se ingresan string y no enteros, que son los datos en que se basa la presente implementacin.

Definicin: Un rbol AVL es un rbol binario de bsqueda en el que las alturas de los subarboles izquierdos y derecho de cualquier nodo difieren a lo sumo en 1. Esta restriccin impuesta sobre la altura de los subarboles de un rbol AVL se le conoce como propiedad de los rboles AVL, y debe ser cumplida por todos y cada uno de los nodos del rbol.

Ejemplos:

(1) Basado en que los rboles AVL son rboles binarios es que a partir de un rbol vaco se han insertado los datos originando el rbol de la Fig. 1, el cual deja de tener la propiedad AVL. Pues, aunque los nodos 2, 4, 10, la posean considerando sus respectivos subarboles, notamos que en este caso la raz, es decir el nodo 8 no posee la propiedad de los rboles AVL pues la altura del subrbol izquierdo no difiere en a lo sumo 1 con el subrbol derecho, (en particular el subrbol izquierdo tiene altura 3, mientras que el subrbol derecho tiene altura 1. ( De all la marca que se considera como 2 bajo el nodo 8 y 1 bajo el nodo 4.

8

4 -2 10

2 -1 6

1

Fig.1

Los valores 2 y 1 se conocen como "Balance" de los nodos 8 y 4 respectivamente. registra los valores de las alturas de los subrboles, los que deben ser -1 (balance_izq), 0 (balanceado) y +1 (balance_der).

(2) En este otro caso, todos los nodos satisfacen la condicin de balance, de manera que es un rbol AVL.

4

2 8

1 3 6 10

Fig. 2

5 7

Sea T(h) cualquier rbol AVL que contenga N(h) nodos, con h>=2. Como T(h) es un rbol AVL, y supongamos que tenga el menor nmero de nodos, entonces uno de los subrboles de la raz debe tener altura h-1 y el otro deber tener altura h-2, de manera que el nmero de nodos de un rbol AVL en el caso peor de altura h viene dado por: (Ver (2), para mayor informacin)

N(h) = 1 + N(h-1) + N(h-2).

Si suponemos que N(h) = 0 cuando h inserta x

// void eliminar( x ) --> elimina x

// Comparable hallar( x ) --> hallar un Elemento que corresponde a x

// Comparable hallarMin( ) --> Entrega el Elemento ms pequeo

// Comparable hallarMax( ) --> Entrega el Elemento ms grande

// boolean esVacio( ) --> Return true si es vacio; else false

// void hacerVacio( ) --> Eliminar todos

// void printArbol( ) --> Salida de los datos en una sucesin ordenada

// void salidaArbolBinario() --> Salida de los datos girados en 90 grados.

/*

* Comparaciones se basan en el mtodo compareTo.(REPASAR)

*/

public class Arbol_Avl

{

/* Raiz del Arbol */

private Nodo_Avl raiz;

/*

* Constructor por defecto

*/

public Arbol_Avl( )

{

raiz = null;

}

/*

* Insertar: Duplicados son ignorados.

* x es el dato a ser insertado.

*/

public void insertar(Comparable x )

{

raiz = insertar( x, raiz );

}

/*

* Eliminar un nodo del Arbol. Caso que x no este,

* nada ocurre.

* Si x esta, es eliminado.

*/

//no esta la implementacin......

/*

* Determinar el elemento ms pequeo en el arbol..

* Devuelve: el dato ms pequeo o null,

* en el caso que el arbol este vacio.

* Analogamente se podra determinar el ms grande elemento en el arbol

*/

//no esta implementado.....

/*

* Eliminar el arbol.

*/

//no esta implementado....

/*

* Test, si el arbol esta vacio o no.

* devuelve true, caso de vacio; sino false.

*/

public boolean esVacio( )

{

return raiz == null;

}

/*

* Entregar el contenido del rbol en una sucesion ordenada.

*/

public void printArbol( )

{

if( esVacio( ) )

System.out.println( "Arbol vacio" );

else

printArbol( raiz );

}

/*

* Salida de los elementos del arbol binario rotados en 90 grados

*/

public void salidaArbolBinario()

{

if( esVacio() )

System.out.println( "Arbol vacio" );

else

salidaArbolBinario(raiz,0);

}

/*

* Metodo interno para tomar un nodo del arbol.

* Parametro b referencia al nodo del arbol.

* Devuelve los elementos o null,

* caso de b sea null.

*/

private Comparable elementAt(Nodo_Avl b )

{

return b == null ? null : b.datos;

}

/*

* Metodo Interno para agregar o insertar un nodo en un subarbol.

* x es el elemento a agregar.

* b es el correspondiente nodo raiz.

* Devuelve la nueva raiz del respectivo subarbol.

*/

private Nodo_Avl insertar(Comparable x, Nodo_Avl b)

{

if( b == null )

b = new Nodo_Avl(x, null, null);

else if (x.compareTo( b.datos) < 0 )

{

b.izq = insertar(x, b.izq );

if (altura( b.izq ) - altura( b.der ) == 2 )

if (x.compareTo( b.izq.datos ) < 0 )

b = RotacionSimpleIzq(b);

else

b = RotacionDobleIzq_Der(b);

}

else if (x.compareTo( b.datos ) > 0 )

{

b.der = insertar(x, b.der);

if( altura(b.der) - altura(b.izq) == 2)

if( x.compareTo(b.der.datos) > 0 )

b = RotacionSimpleDer(b);

else

b = RotacionDobleDer_Izq(b);

}

else

; // Duplicados; no hace nada

b.altura = max( altura( b.izq ), altura( b.der ) ) + 1;

return b;

}

/*

* Metodo Interno para determinar el dato ms pequeo.

* b es la raiz.

* Devuelve: Nodo con el elemento mas pequeo.

*/

private Nodo_Avl hallarMin(Nodo_Avl b)

{

if (b == null)

return b;

while(b.izq != null )

b = b.izq;

return b;

}

/*

* Analogamente al anterior pero el ms grande.

*/

private Nodo_Avl hallarMax(Nodo_Avl b )

{

if (b == null)

return b;

while (b.der != null)

b = b.der;

return b;

}

/*

* Metodo interno para determinar un dato.

* x es el dato buscado

* b es la raiz

* Devuelve: Nodo con el correspondiente dato.

*/

private Nodo_Avl hallar(Comparable x, Nodo_Avl b)

{

while( b != null )

if (x.compareTo( b.datos) < 0 )

b = b.izq;

else if( x.compareTo( b.datos ) > 0 )

b = b.der;

else

return b; // paso

return null; // no paso nada

}

/*

* Metodo Interno para devolver los datos de un subarbol en una sucesion ordenada.

* b es la raiz.

*/

private void printArbol(Nodo_Avl b)

{

if( b != null )

{

printArbol( b.izq );

System.out.println( b.datos );

printArbol( b.der );

}

}

/*

* salida del arbol binario rotado en 90 Grados

*/

private void salidaArbolBinario(Nodo_Avl b, int nivel)

{

if (b != null)

{

salidaArbolBinario(b.izq, nivel + 1);

for (int i = 0; i < nivel; i++)

{

System.out.print(' ');

}

System.out.println(b.datos);

salidaArbolBinario(b.der, nivel + 1);

}

}

/*

* Salida: altura de los nodos, o -1, en el caso null.

*/

private static int altura(Nodo_Avl b)

{

return b == null ? -1 : b.altura;

}

/*

* Salida: Maximum entre lhs y rhs.

*/

private static int max( int lhs, int rhs )

{

return lhs > rhs ? lhs : rhs;

}

/*

* Rotacion Simple Izquierda(simetrica a Rotacion Simple Derecha).

* Para los arboles AVL, esta es una de las simples rotaciones.

* Actualiza la altura, devuelve la nueva raiz.

*/

private static Nodo_Avl RotacionSimpleIzq(Nodo_Avl k2)

{

Nodo_Avl k1 = k2.izq;

k2.izq = k1.der;

k1.der = k2;

k2.altura = max( altura( k2.izq ), altura( k2.der ) ) + 1;

k1.altura = max( altura( k1.izq ), k2.altura ) + 1;

return k1;

}

/*

* Rotacin Simple Derecha.

*/

private static Nodo_Avl RotacionSimpleDer(Nodo_Avl k1)

{

Nodo_Avl k2 = k1.der;

k1.der = k2.izq;

k2.izq = k1;

k1.altura = max( altura( k1.izq ), altura( k1.der ) ) + 1;

k2.altura = max( altura( k2.der ), k1.altura ) + 1;

return k2;

}

/*

* Rotacion doble: primero hijo izquierdo con su hijo derecho

* entonces nodo k3 con el nuevo hijo izquierdo.

* para los arboles AVL, esta es una doble rotacin

* actualiza alturas, entrega nueva raiz.

*/

private static Nodo_Avl RotacionDobleIzq_Der(Nodo_Avl k3)

{

k3.izq = RotacionSimpleDer( k3.izq );

return RotacionSimpleIzq( k3 );

}

/*

* rotacion doble: primero hijo derecho

* con su hijo izquierdo; luego nodo k1 con nuevo hijo derecho.

* Para los AVL, esta es una doble rotacin.

* actualiza alturas, entrega nueva raiz.

*/

private static Nodo_Avl RotacionDobleDer_Izq(Nodo_Avl k1)

{

k1.der = RotacionSimpleIzq(k1.der);

return RotacionSimpleDer(k1);

}

}

archivo Arbol_AvlTest.java

(Dr. Eric Jeltsch F.)

public class Arbol_AvlTest

{

// Programa Test

public static void main(String [] args)

{

Arbol_Avl b1 = new Arbol_Avl();

Arbol_Avl b2 = new Arbol_Avl();

for (int i = 0; i < 7; i++) //

{

Integer r = new Integer(i);

b1.insertar(r);

}

System.out.println("Arbol girado en 90 grados");

b1.salidaArbolBinario();

for (int i = 0; i < 10; i++)

{

// Genera un nmero entre 0 y 100

Integer r = new Integer((int)(Math.random()*100));

b2.insertar(r);

}

System.out.println("Arbol girado en 90 grados");

b2.salidaArbolBinario();

System.out.println("Travesia en Inorden(Izq-Raiz-Der)");

b2.printArbol();

}

}

Salida que se genera:

Arbol girado en 90 grados

0

1

2

3

4

5

6

Arbol girado en 90 grados

4

14

35

39

52

64

74

75

77

Travesia en Inorden(Izq-Raiz-Der)

4

14

35

39

52

64

74

75

77

Interpretacin de la salida

Arbol girado en 90 grados

0

1

2

3

4

5

6

La implementacin de los rboles AVL, as como su salida estn basados en los ejemplos y materiales entregados en (3).

3

1 5

0 2 4 6

Propuestas: Una mejora factible de considerar en la implementacin del mtodo insertar es considerar que los elementos a ingresar son String o caracteres, adems de considerar el factor de balance y la nueva raz que se obtiene. Como se muestra en el ejemplo siguiente.

caracter que desea insertar al arbol-AVL (Borrar: \n): a

a insertado

AVL con balanceo:

a(0)

Caracter que desea insertar al arbol-AVL (Borrar: \n): b

b insertado

AVL con balanceo:

b(0)

a(1)

c insertado

AVL con balanceo:

c(0)

b(0)

a(0)

Bibliografa:

(1) Mark Allen Weiss , "Data Structures and Algorithm Analysis (in Java)", Addison_Wesley, 1999.

(2) Gregory Heileman, Estructuras de Datos, Algoritmos y Programacin Orientada a Objetos, Mc Graw Hill, 1997.

(3) Documentos POO(2003) y apresto a UML, en la direccin Web http://dns.uls.cl/~ej/java-2003/Labor2003/Praxis3Web/practica3.htm(4) Cormen, Leiserson, Rivest, "Introduction to algorithms", McGraw-Hill, 1990.

1____________________________________________________________________Area de Computacin, Universidad de La Serena