Está en la página 1de 18

Introduccin

Hasta ahora nos hemos dedicado a estudiar TAD es que de una u otra forma eran de naturaleza lineal, o unidimensional. En los tipos abstractos de datos lineales existen exactamente un elemento previo y otro siguiente (excepto para el primero y el ltimo, si los hay); en las estructuras no lineales, como conjuntos o rboles, este tipo de secuencialidad no existe, aunque en los rboles existe una estructura jerrquica, de manera que un elemento tiene un solo predecesor, pero varios sucesores1.

Profesor Sergio Alves (www.ciens.ucv.ve/.../documentos/ProfSergioAlves_UMA_TDA_Arbol.pdf)

rbol binario Un rbol impone una estructura jerrquica sobre una coleccin de objetos. Ejemplos claros de utilizacin de rboles se presentan tanto dentro como fuera del rea de computacin (ndices de libros, rboles genealgicos, etc.); en Informtica constituyen una de las estructuras ms utilizadas, con aplicaciones que van desde los rboles sintcticos utilizados para la representacin y/o interpretacin de trminos de un lenguaje o expresiones aritmticas, pasando por los arboles de activacin de procedimientos recursivos, hasta la representacin de datos que se desea mantener ordenados con un tiempo de acceso relativamente bajo. En general, se usarn rboles siempre que se quiera representar informacin jerarquizada, cuando esta converja en un solo punto Tambin se define como un conjunto finito de elementos (nodos) que bien est vaco o est formado por una raz con dos rboles binarios disjuntos, es decir, dos descendientes directos llamados subrbol izquierdo y subrbol derecho. Los rboles binarios (tambin llamados de grado 2) tienen una especial importancia. Las aplicaciones de los arboles binarios son muy variadas ya que se les puede utilizar para representar una estructura en la cual es posible tomar decisiones con d opciones en os distintos puntos. La representacin grfica de un rbol binario

IMPLEMENTACIN DEL RBOL BINARIO. Como es usual se presentan dos posibles implementaciones: dinmica, usando variables puntero, o esttica, basadas en arrays; adems de mltiples variantes en cada una de estas modalidades. Cualquiera de ellas tendr, sin embargo, un mismo mdulo de definicin:

DEFINITION MODULE ArbolB; TYPE ITEM = << cualquier tipo >>; ArbolB; ERROR = (SinError, ArbolVacio, SinMemoria); VAR error : ERROR; PROCEDURE Crear(): ArbolB; PROCEDURE EsVacio(a: ArbolB): BOOLEAN; PROCEDURE ArbolBinario(i: ITEM; l, r: ArbolB): ArbolB; PROCEDURE Raiz(a: ArbolB): ITEM; PROCEDURE HijoIzq(a: ArbolB): ArbolB;

PROCEDURE HijoDch(a: ArbolB): ArbolB; END ArbolB. Para su creacin tambin se puede utilizar el siguiente cdigo es: Void nuevoArbol(ArbolBinario* raz, ArbolBinario ramaIzq, TipoElemento x, ArbolBinario ramaDer) { *raiz=crearNodo(x) (*raz) >izq=ramaIzq (*raz) >der=ramaDer } ArbolBinario crearNodo(TipoElemento x) { ArbolBinario a a=(ArbolBinario) malloc(sizeof(Nodo)) a.dato=x a.Izq=a.Der=NULL return a } Implementacin dinmica. Cada nodo en un rbol est compuesto por un dato del tipo ITEM, un puntero al subrbol izquierdo y otro al derecho. Esto sugiere la utilizacin de un registro con tres campos: TYPE ARBOL = POINTER TO NODO; NODO = RECORD Valor: ITEM;

Izquierdo, Derecho: ARBOL END; En donde el tipo ITEM ha sido importado del mdulo en que fue definido. Veamos algunos ejemplos de rboles (rbol no equilibrado en altura, y degenerado):

Una vez definido el tipo podemos implementar los procedimientos de acceso, asegurando que estos satisfagan las especificaciones algebraicas. Con esta definicin de tipo, el procedimiento Crear slo tiene que devolver un puntero a NIL. PROCEDURE Crear(): ArbolB; (* Postcondicin: devuelve un rbol vaco *) BEGIN RETURN NIL END Crear; El procedimiento EsVacio se limitar, por tanto, a comprobar que el rbol a es un puntero nulo. PROCEDURE EsVacio(a: ArbolB): BOOLEAN; (* Postcondicin: devuelve TRUE si a es vaco; en otro caso FALSE *) BEGIN RETURN (a=NIL) END EsVacio;

Es fcil comprobar que es TRUE la expresin booleana EsVacio(Crear()), mientras que EsVacio (ArbolBinario(i, l, r)) es FALSE, verificando los dos axiomas de su especificacin. El procedimiento ArbolBinario toma dos rboles y un valor, y produce un nuevo rbol insertando el valor en la raz y usando estos rboles como sus subrboles derecho e izquierdo. Lo nico que debe hacerse es crear un nuevo nodo para dicha raz. PROCEDURE ArbolBinario(i: ITEM; l, r: ArbolB): ArbolB; (* Postcond.: devuelve un rbol binario que contiene i como valor de su raz y l y r como subrboles izq. y dch. respectivamente *) VAR temp: ArbolB; BEGIN NEW(temp); WITH temp^ DO valor := i; izquierdo := l; derecho := r END; RETURN temp END ArbolBinario; El nmero de celdas de memoria utilizadas se incrementa en uno con cada llamada a ArbolBinario. El procedimiento Raiz devuelve el valor contenido en la raz del rbol. Debemos asegurar que se detectan las situaciones especificadas en las precondiciones y, en caso de producirse, debe aplicarse el correspondiente tratamiento de errores; el mecanismo empleado en esta implementacin consisten en la generacin de un mensaje de error, y la terminacin del

programa. en caso de ser una situacin correcta, simplemente se devuelve el contenido del campo valor del nodo primero, o raz. Para comprobar que se verifica el axioma Raiz(ArbolBinario(i,l,r))=i, vemos que ArbolBinario asigna i al campo valor del nodo situado en la raz del rbol que construye, y Raiz devuelve el contenido del campo valor del rbol que le es pasado como argumento. PROCEDURE Raiz(a: ArbolB): ITEM; (* Postcond.: devuelve el contenido de la raz del rbol binario a *) BEGIN IF EsVacio(a) THEN WrStr("Error: rbol vaco"); HALT ELSE RETURN a^.valor END END Raiz; La funcin selectora HijoIzq devuelve el subrbol izquierdo del rbol que le es pasado, dejando el rbol que recibe sin cambio. De los axiomas para el procedimiento sabemos que un intento de obtener el subrbol izquierdo de un rbol vaco debe resultar en una situacin de error, y como es usual, es lo primero que se comprueba. En otro caso, se devuelve el puntero almacenado en el campo izquierdo del rbol. PROCEDURE HijoIzq(a: ArbolB): ArbolB; (* Postcondicin: devuelve el subrbol izquierdo de a *) BEGIN IF EsVacio(a) THEN WrStr("Error: rbol vaco"); HALT

ELSE RETURN a^.izquierdo END END HijoIzq; HijoIzq devuelve el campo izquierdo del nodo situado en la raz del rbol, luego el resultado de HijoIzq(ArbolBinario(i, l, r) es el rbol l, lo que verifica el axioma correspondiente. El procedimiento HijoDch tiene un comportamiento idntico al anterior, con la nica diferencia de que acta con el subrbol derecho en lugar de con el izquierdo. PROCEDURE HijoDch(a: ArbolB): ArbolB; (* Postcondicin: devuelve el subrbol derecho de a *) BEGIN IF EsVacio(a) THEN WrStr("Error: rbol vaco"); HALT ELSE RETURN a^.derecho END; END HijoDch; Con esta implementacin la cantidad de espacio utilizado es proporcional al nmero de operaciones ArbolBinario realizadas, ya que es el nico procedimiento que hace una llamada a NEW.

Desventajas tpicas de una implementacin dinmica: - La memoria necesaria se toma en tiempo de ejecucin. - Todos los accesos a la informacin deben hacerse de forma indirecta.

Recorrido de un rbol binario Recorrer el rbol significa que cada nodo sea procesado una vez y solo una en una secuencia determinada Existen 2 enfoques generales Procesamiento en amplitud Con esta tcnica se pretende visitar los nodos de un rbol, por niveles: primero los del nivel 1, luego los del nivel 2, luego los del 3, y as sucesivamente. En el siguiente ejemplo, los nodos se visitaran en el siguiente orden: A, C, B, D, G, H, F, E, J,

Procesamiento en profundidad. Hay tres mtodos para visitar un rbol en profundidad: Preorden Inorden postorden.

Inorden Inorden, se visita la raz entre la visita de los subrboles izquierdo y derecho, o sea, se visita primero el subrbol izquierdo, despus la raz, y por ltimo el subrbol derecho. En el caso de rboles generales o de orden N, se visita primero el rbol ms a la izquierda, a continuacin la raz, y por ltimo el resto de subrboles en secuencia. Exiten dos formas de implementar el inorden; Caso 1

Caso 2

Un ejemplo:

El recorrido en inorden del rbol es: 4, 6, 10, 15, 17, 20, 22.

Preorden Preorden, la raz se visita antes de visitar los subrboles izquierdo y derecho en preorden. Para la implementacin del recorrido en Preorden (RID) utilizaremos el siguiente codigo.

O tambin de la siguente forma: void preOrden(ArbolBinario raz) { if(raiz) { visitar(raiz >dato) preOrden(raiz >izq) preOrden(raiz >der) } } Un ejemplo:

El recorrido en PreOrden del rbol anterior es el siguiente: 15, 6, 4, 10, 20, 17, 22 Postorden En postorden, primero se visitan el subrbol izquierdo, luego el derecho (ambos en postorden), y por ltimo la raz. Para la implementacin del Postorden(IDR) utilizaremos;

Tambien se puede implementar de la siguiente forma void PostOrden(ArbolBinario raz) { if(raiz) { PostOrden(raiz >izq) PostOrden(raiz >der) visitar(raiz >dato) } } Un ejemplo:

El recorrido en PostOrden(IDR) del rbol anterior es: 4, 10, 6, 17, 22, 20, 15

RBOL BINARIO DE BSQUEDA El rbol binario de bsqueda (ABB) toma su nombre del mtodo de bsqueda dicotmico visto para listas ordenadas, que usaba un array para mantener un conjunto de items (nmero de items limitado, y operaciones de insercin y borrado de elementos costosas). Una implementacin dinmica sera muy ineficiente. Otra solucin consistira en utilizar un rbol para mantener la informacin ordenada, con operaciones de insercin y extraccin muy eficientes. El TAD ABB es un rbol binario en el que los nodos estn ordenados. El orden impuesto a los nodos es tal que para cada nodo, todos los valores de su subrbol izquierdo son menores que su valor, y todos los valores del derecho son mayores. Evidentemente, el tipo base requiere una relacin de orden total. La insercin de los nmeros 46, 35, 74, 39, 42, 49, 23, 73, 80 y 96 produce:

La localizacin de un valor en el rbol se realizar recorriendo el rbol, y tomando el rbol derecho o el izquierdo dependiendo de que el valor buscado sea mayor o menor que el de la raz del rbol, respectivamente. Esto nos permite mantener la eficiencia y flexibilidad de una implementacin dinmica con rdenes de complejidad para la bsqueda similares a los de la implementacin esttica con elementos ordenados. Sin embargo, no todos los rboles binarios mantienen esta eficiencia; dependiendo de la forma en que se realice la insercin de los elementos obtendremos representaciones muy dispares. As, el rbol anterior tambin se podra haber representado como sigue:

As podemos ver como una misma coleccin de elementos puede tener muchas representaciones posibles como rboles de bsqueda, con alturas muy diferentes. En el ltimo grfico podemos observar como la rama izquierda es mucho mayor que la derecha. En el siguiente ejemplo, nos resulta un rbol degenerado incluso, y como cada nodo tiene vaco su subrbol izquierdo, resulta un rbol con altura igual a su nmero de nodos, siendo esencialmente una lista lineal.

Implementaciones del rbol binario de bsqueda. A continuacin vemos la implementacin dinmica correspondiente a esta especificacin. Suponemos que los elementos de tipo ITEM pueden ser comparados mediante los operadores relacionales tpicos. Si no es este el caso, sera necesario incluir en los procedimientos Insertar(), Eliminar y Esta(), un parmetro adicional que permita saber cuando un ITEM es mayor, igual, o menor que otro. DEFINITION MODULE ArbolBB; FROM ArbolB IMPORT ITEM; TYPE ABB; PROCEDURE Crear(): ABB; PROCEDURE Insertar(i: ITEM; A: ABB): ABB; PROCEDURE Eliminar(i: ITEM; A: ABB): ABB; PROCEDURE Esta(i: ITEM; A: ABB): BOOLEAN; END ArbolBB. IMPLEMENTATION MODULE ArbolBB; FROM IO IMPORT WrStr;

FROM ArbolB IMPORT ArbolB, ArbolBinario, Raiz, HijoIzq, HijoDch, EsVacio; IMPORT ArbolB; TYPE ABB = ArbolB; PROCEDURE Crear(): ABB; BEGIN RETURN ArbolB.Crear() END Crear; PROCEDURE Insertar(i: ITEM; A: ABB): ABB; BEGIN IF EsVacio(A) THEN RETURN ArbolBinario(i, ArbolB.Crear(), ArbolB.Crear()) ELSIF i = Raiz(A) THEN RETURN A ELSIF i < Raiz(A) THEN RETURN ArbolBinario(Raiz(A), Insertar(i, HijoIzq(A)), HijoDch(A)) ELSE RETURN ArbolBinario(Raiz(A), HijoIzq(A), Insertar(i, HijoDch(A))) END END Insertar; PROCEDURE Minimo(A: ABB): ITEM; BEGIN IF EsVacio(A) THEN WrStr("Error: rbol Nulo");

HALT ELSIF EsVacio(HijoIzq(A)) THEN RETURN Raiz(A) ELSE RETURN Minimo(HijoIzq(A)) END END Minimo; PROCEDURE Eliminar(i: ITEM; A: ABB): ABB; BEGIN IF EsVacio(A) THEN RETURN ArbolB.Crear() ELSIF i = Raiz(A) THEN IF EsVacio(HijoIzq(A)) THEN RETURN HijoDch(A) ELSIF EsVacio(HijoDch(A)) THEN RETURN HijoIzq(A) ELSE RETURN ArbolBinario( Minimo(HijoDch(A)), HijoIzq(A), Eliminar(Minimo(HijoDch(A)), HijoDch(A))) END ELSIF i < Raiz(A) THEN

RETURN ArbolBinario(Raiz(A), Eliminar(i, HijoIzq(A)), HijoDch(A)) ELSE RETURN ArbolBinario(Raiz(A), HijoIzq(A), Eliminar(i, HijoDch(A))) END END Eliminar; PROCEDURE Esta(i: ITEM; A: ABB): BOOLEAN; BEGIN RETURN (NOT EsVacio(A)) AND ((i = Raiz(A)) OR Esta(i, HijoIzq(A)) OR Esta(i, HijoDch(A))) END Esta; END ArbolBB.

Bibliografa Recursos de internet www.ciens.ucv.ve/.../documentos/ProfSergioAlves_UMA_TDA_Arbol.pdf (consultado el 10-072011). www.algoritmia.net/articles/arboles/arboles.doc (consultado el 10-07-2011). www.ucema.edu.ar/~rst/Algoritmos_y...de.../5._Arboles_binarios.pdf (consultado el 10-072011). profesores.elo.utfsm.cl/~tarredondo/.../ELO-320%20Arboles%20binarios.p.. (consultado el 1007-2011).mit.ocw.universia.net/1.00/s02/class-sessions/lecture-26/lecture-26.pdf (consultado el 10-072011).eii.ucv.cl/pers/guidi/cursos/estructuras/pdf/Estructuras-ArbolesBinarios.pdf (consultado el 1007-2011).delta.cs.cinvestav.mx/~adiaz/anadis/BinTree.pdf (consultado el 10-07-2011).-

También podría gustarte