• No se han encontrado resultados

Estructuras de Datos y Algoritmos. Curso 2004/05 Tema 6. Árboles y Árboles Binarios

N/A
N/A
Protected

Academic year: 2022

Share "Estructuras de Datos y Algoritmos. Curso 2004/05 Tema 6. Árboles y Árboles Binarios"

Copied!
12
0
0

Texto completo

(1)

Estructuras de Datos y Algoritmos. Curso 2004/05 Tema 6. ´ Arboles y ´ Arboles Binarios

Mabel Galiano Natividad Prieto

Departamento de Sistemas Inform´ aticos y Computaci´ on Escuela T´ ecnica Superior de Inform´ atica Aplicada

´Indice

1. Introducci´on a las Estructuras Jer´arquicas: ´Arboles 2 1.1. Conceptos generales . . . 3 1.2. ´Arboles Binarios: definici´on, propiedades y tipos de Recorrido . . . 4 1.3. Representaci´on Contigua de un ´Arbol Binario Completo . . . 8 1.4. Representaci´on Enlazada de un ´Arbol Binario General: el concepto de Nodo Binario 9 2. Implementaci´on en Java de un ´Arbol Binario General 9 2.1. La clase ArbolBinario . . . 9 2.2. La clase NodoBinario . . . 10

Objetivos y Bibliograf´ıa

El objetivo general de este tema es introducir y estudiar el Arbol Binario´ como la estruc- tura jer´arquica b´asica a partir de la cual se obtienen tanto el Mont´ıculo BinariooHeapcomo el Arbol Binario de B´´ usqueda, que se presentar´an m´as tarde en la asignatura como posibles Im- plementaciones de alguno de los Modelos avanzados, bien Cola de Prioridad o bien Diccionario.

Para ello, a partir de los conceptos generales asociados al ´Arbol, se definir´a el ´Arbol Binario, sus propiedades y operaciones tanto b´asicas como de Recorrido (In-Orden, Pre-Orden, Post-Orden y Por Niveles). Adem´as, se presentar´an sus dos Representaciones posibles: contigua para un Arbol Binario Completo, que se utilizar´´ a para representar un Mont´ıculo, y enlazada para un Arbol Binario general, que ser´´ a el fundamento de la Representaci´on de los ´Arboles Binarios de B´usqueda y en funci´on de la cual se dise˜nar´a en Java la clase ArbolBinario que representa un Arbol Binario general mediante un ´´ unico Enlace a su Nodo ra´ız, esto es como una estructura Enlazada de Objetos de la clase NodoBinario.

Como bibliograf´ıa b´asica de este tema se utilizar´an los siguientes cap´ıtulos y apartados del libro de Weiss, M.A. Estructuras de datos en Java: el apartado 5 del cap´ıtulo 6 para la introducci´on de las estructuras de ´Arbol y ´Arbol Binario y los apartados del 1 al 3 del cap´ıtulo 17 para lo referente a las clases Java ArbolBinario y NodoBinario.

(2)

1. Introducci´ on a las Estructuras Jer´ arquicas: ´ Arboles

En ocasiones los Datos de una Colecci´on mantienen relaciones de tipo Jer´arquico que no es posible expresar mediante una Representaci´on Lineal de la Colecci´on, como la Lista Enlaza- da Indirecta o el simple array estudiadas en el tema anterior. Por ejemplo, son claramente jer´arquicas las relaciones que mantienen los distintos directorios, y ficheros, en los que se or- ganiza la informaci´on de un Sistema Operativo o los operadores y operandos que conforman una expresi´on aritm´etica a evaluar durante la compilaci´on o interpretaci´on de un programa.

En estos casos, la forma m´as natural de representar la Colecci´on es la de Arbol,´ la estructura Jer´arquica por excelencia; la siguiente figura muestra gr´aficamente el ´Arbol que representa la Colecci´on de Directorios de las pr´acticas de EDA a partir del directorio home de un usuario:

$HOME

EDA

libJava progJava

estructurasDeDatos util misFiguras bancoDeModems

lineales jerarquicos hashing

En cuanto a la expresi´on aritm´etica (((a*b)+(c+d))*(e-f)), en notaci´on infija y parenti- zada, se muestra a continuaci´on el ´Arbol que la puede representar:

+

d

* b

a c

e f

+

*

Muy importante tambi´en para los prop´ositos de la asignatura resulta destacar que la es- tructura en ´Arbol, adem´as de representar las relaciones jer´arquicas existentes entre los Datos de una Colecci´on, puede favorecer la B´usqueda Din´amica caracter´ıstica de los Modelos Cola de Prioridad y Diccionario en tiempos sublineales, que como es sabido no consigue su Rep- resentaci´on Lineal. Por ejemplo, si se desea representar la Colecci´on de Palabras mes, mesa, meta, metro, coro y corona cualquier estructura Lineal requiere un tiempo de B´usqueda del orden del n´umero de Palabras que la forman, mientras que el ´Arbol de Palabras (Trie) que se muestra a continuaci´on s´olo exige un tiempo proporcional a la longitud de la Palabra buscada:

m e s a

t

c o r

o n a r

o a

(3)

Otro ejemplo significativo de B´usqueda Din´amica eficiente es el que se consigue con ´Arboles como el que muestra la siguiente figura y que representa la Colecci´on de Integer 100, 50, 200, 25, 75, 150, 300 y 180:

100

200

25 75 150 300

50

180

En este ´Arbol, cara a favorecer cualquier proceso de B´usqueda Binaria (insertar, borrar o buscar un Dato), los Integer de la Colecci´on se disponen de la siguiente forma ordenada: el primero, el 100, ocupa la Ra´ız del ´Arbol y a partir de ´esta, cada Dato menor que el primero se sit´ua en la parte izquierda del ´Arbol y cada Dato mayor en la derecha; adem´as, para cada sub- Arbol o parte de ´´ este, el proceso se repite. Por ejemplo, el Dato 75 al ser menor que 100 pero mayor que 50 se sit´ua a la izquierda de la Ra´ız, ocupada por 100, y a la derecha del sub- ´Arbol cuya Ra´ız ocupa 50; con ello bastar´an 2 comparaciones para encontrar el Integer 200 en el Arbol. ´´ Arboles de este tipo, denominados ´Arboles Binarios de B´usqueda, se estudiar´an m´as adelante con detalle para conocer bajo qu´e condiciones espec´ıficas garantizan una B´usqueda Din´amica con coste logar´ıtmico.

1.1. Conceptos generales

Un Arbol´ es una estructura Jer´arquica que se puede definir por medio de un conjunto de Nodos, uno de los cuales es distinguido como la Ra´ız del ´Arbol, y un conjunto de Aristas tal que cualquier Nodo H, a excepci´on de la Raiz, est´a conectado por medio de una Arista a un

´unico Nodo P; se dice entonces que P es el Padre de H y H es un Hijo de P. Si un Nodo no tiene ning´un Hijo se denomina Hoja; excluidas las Hojas, al resto de Nodos del ´Arbol, los que tienen alg´un Hijo, se les denomina Internos. Para ejemplificar las definiciones realizadas, en la siguiente figura se muestra un ´Arbol con 14 Nodos etiquetados con las Letras de la A a la N:

I M B

D E F G H

C A

L K J N

Figura 1: ´Arbol Ejemplo con 14 Nodos

N´otese que el Nodo etiquetado como A es la Ra´ız del ´Arbol y B y C son sus Hijos; el Nodo etiquetado con C es el Padre de los Nodos F, G y H y el Nodo I tiene dos Hijos etiquetados como

(4)

M y N. Asimismo, los Nodos con las etiquetas D, M, N, F, J, K y L son Hojas y el resto Nodos Internos.

Caminos entre Nodos: Profundidad, Nivel y Altura de un Nodo

Un ´Arbol se caracteriza porque desde la Ra´ız a cada uno de los Nodos hay un Camino´unico cuyaLongitudviene dada por el n´umero de Aristas que lo componen. Por ejemplo, en el ´Arbol de la Figura 1 el Camino desde la Ra´ız hasta la Hoja etiquetada como N es A-B-E-I-N y tiene longitud 4.

A partir de la Longitud de un Camino se definen la Profundidad, el Nivel y la Altura de un Nodo y un ´Arbol. Se denomina Profundidad de un Nodo a la Longitud del Camino que va desde la Ra´ız hasta ´el; por tanto, la Profundidad de la Ra´ız es 0. Adem´as, se dice que todos los Nodos que est´an a la misma Profundidad est´an en el mismo Nivel, siendo cero el de la Ra´ız. Por ejemplo, en la Figura 1 los Nodos D, E, F, G y H ocupan el Nivel 2, pues todos ellos tienen la misma Profundidad, tambi´en 2. Esta misma figura permite tambi´en observar que la representaci´on gr´afica que se hace de un ´Arbol es precisamente por Niveles, empezando por el de la Ra´ız, el cero, hasta el que ocupan las Hojas. Finalmente, la Altura de un Nodo se define como la Longitud del Camino que va desde dicho Nodo hasta la Hoja m´as profunda bajo ´el.

En base a esta definici´on, la Altura de un ´Arbol es la de su Nodo Ra´ız, 4 la del ´Arbol de la Figura 1.

Relaciones entre Nodos: Tama˜no de un Nodo

Utilizando la nomenclatura t´ıpica de la Genealog´ıa, a los Nodos de un ´Arbol que tienen el mismo Padre se les denomina Hermanos; as´ı, en el ´Arbol de la Figura 1 los Nodos F, G y H son Hermanos porque tienen el mismo Padre, el Nodo etiquetado con C. Asimismo, si hay un Camino desde el Nodo u hasta el Nodo v, se dice que u es un Ascendiente de v y que v es un Descendiente de u. Si u = v, entonces u es unAscendiente Propiode v y v es un Descendiente Propio de u; as´ı, en el ´Arbol ejemplo son Ascendientes Propios del Nodo etiquetado con N los Nodos I, E, B y A y son Descendientes propios de C los Nodos F, G, H, J, K y L.

En base a la nomenclatura que se acaba de introducir, el Tama˜no de un Nodo se define como el n´umero de Descendientes que tiene y el de un ´Arbol como el de su Nodo Ra´ız. Por ejemplo, el Tama˜no del Nodo C de la Figura 1 es 7, el del Nodo B es 6 y el del ´Arbol, i.e. el de su Nodo Ra´ız, es 14.

Definici´on Recursiva de un ´Arbol

Una definici´on de ´Arbol alternativa a la presentada es la recursiva. Seg´un ´esta, un ´Arbol es bien un ´Arbol vac´ıo o bien un Nodo Ra´ız y cero o m´as sub- ´Arboles no vac´ıos, cada una de cuyas Ra´ıces est´a conectada por medio de una Arista con la Ra´ız del ´Arbol.

Lo interesante de esta definici´on es que permite identificar el concepto de Nodo con el de Arbol:´ un Nodo define el ´Arbol del que es Ra´ız. Ser´a al hablar de ´Arboles Binarios cuando se explotar´a esta identificaci´on.

1.2. Arboles Binarios: definici´ ´ on, propiedades y tipos de Recorrido

UnArbol Binario´ es un ´Arbol en el que ning´un Nodo puede tener m´as de dos Hijos, que por ello pueden ser distinguidos comoHijo Izquierdo eHijo Derecho. N´otese c´omo el ´Arbol ejemplo que se ha venido utilizando hasta ahora, Figura 1, no es un ´Arbol Binario: tiene un Nodo, el etiquetado con C, que tiene 3 Hijos; sin embargo, el que muestra la siguiente figura s´ı lo es y

(5)

tiene 7 Nodos etiquetados: con A la Ra´ız, con B la Ra´ız de su Hijo Izquierdo y con C la de su Hijo Derecho (que a su vez, n´otese, s´olo tiene Hijo Izquierdo, que es el Nodo F).

B

D E F

C A

G

En la siguiente figura aparece un ´Arbol Binario que s´olo difiere del que se acaba de presentar en que su Nodo F es Hijo Derecho, y no Izquierdo, de C:

B

D E

A

G

C

F

Como se puede demostrar f´acilmente por Inducci´on, en un ´Arbol Binario de Altura H el n´umero m´aximo de Nodos del Nivel i es 2i, 0 ≤ i ≤ H. A partir de este resultado y en base a las definiciones previamente realizadas se pueden establecer los siguientes:

1. su n´umero m´aximo de Nodos es 

i = 0 ... H 2i = 2H+1 − 1;

2. su n´umero m´aximo de Hojas es (2H+1 − 1) − (

i = 0 ... H-1 2i) = 2H; 3. su n´umero m´aximo de Nodos Internos es (2H+1 − 1) − (2H) = 2H − 1.

Arbol Binario Lleno y Completo´

Un ´Arbol Binario de Altura H es Lleno si tiene todos sus Niveles completos, esto es si en cada Nivel i, 0 ≤ i ≤ H, tiene exactamente 2i Nodos. Por ejemplo, el ´Arbol Binario de Altura 3 que muestra la siguiente figura es Lleno:

A partir de esta definici´on, en base a las propiedades expuestas para un ´Arbol Binario, es inmediato deducir que en un ´Arbol Binario Lleno de Tama˜no N y Altura H se cumplen las siguientes propiedades: H = log2 N y N = 2H+1 − 1.

Asimismo, se dice que un ´Arbol Binario es Completosi tiene todos sus Niveles completos a excepci´on quiz´as del ´ultimo que, entonces, debe de tener situados todos sus Nodos, las Hojas del ´Arbol, tan a la izquierda como sea posible; por ejemplo, el ´Arbol Binario que aparece en la siguiente figura es un ´Arbol Binario Completo:

(6)

N´otese que mientras un ´Arbol Binario Lleno es Completo no es cierta la afirmaci´on inversa, por lo que para la Altura y Tama˜no de un ´Arbol Binario Completo se cumplen, respectiva- mente, las siguientes desigualdades: H ≤ log2 N y 2H ≤ N ≤ 2H+1 − 1.

A modo de resumen, y para su uso posterior en la asignatura, conviene destacar ahora que la relaci´on expresada entre la Altura H y el N´umero de Nodos N de un ´Arbol Binario Completo (o Lleno) le confiere una caracter´ıstica muy importante: es Equilibrado, pues los N Datos de una Colecci´on se distribuyen en ´el de forma que la longitud de su Camino m´as largo, i.e. H, es a lo sumo log2 N.

Definici´on Recursiva de ´Arbol Binario

De forma an´aloga a la empleada para un ´Arbol, y como se expresa gr´aficamente en la siguiente figura, un ´Arbol Binario se define recursivamente bien como un ´Arbol Binario vac´ıo o bien como un Nodo Ra´ız y dos sub- ´Arboles Binarios, uno Izquierdo y otro Derecho, que pueden ser vac´ıos.

RAIZ

HIJO IZQUIERDO HIJO DERECHO

Figura 2: Representaci´on gr´afica de un ´Arbol Binario definido recursivamente

Esta definici´on resulta de gran utilidad para lograr implementar un ´Arbol Binario General, por lo que se emplear´a repetidamente en el resto del tema. En primer lugar, al identificar los conceptos de ´Arbol y Nodo, permite que un ´Arbol Binario se represente mediante un Enlace a su Nodo (Binario) Ra´ız y que, por tanto, las operaciones sobre un ´Arbol Binario sean opera- ciones que efectivamente se realizan, se lanzan, sobre su Nodo Ra´ız. En segundo lugar, aunque igualmente importante, proporciona una descomposici´on recursiva del ´Arbol Binario en base a la cual es posible dise˜nar f´acil y naturalmente la mayor´ıa de sus operaciones; a modo de ejemplo, obs´ervese que el Tama˜no o n´umero de Nodos del ´Arbol Binario que muestra la Figura 2 se define recursivamente bien como cero si el ´Arbol Binario es vac´ıo y sino como la suma del Tama˜no de su Ra´ız, esto es 1, y la del Tama˜no de sus Hijos Izquierdo y Derecho.

Operaciones de un ´Arbol Binario

A continuaci´on se clasifican en base a su coste las operaciones que se pueden realizar sobre un Arbol Binario, o equivalentemente sobre su Nodo (Binario) Ra´ız; al presentarlas se describir´´ an

(7)

de manera somera, reservando para la ´ultima secci´on de este tema la definici´on de sus perfiles y los detalles de su implementaci´on en Java:

1. Operaciones B´asicas o de coste del orden de una constante. Agrupadas por su funcionali- dad, ´estas son: dos constructoras, la de un ´Arbol Binario vac´ıo y la de una de sus Hojas, i.e. la de un ´Arbol con un ´unico Nodo Ra´ız compuesto por un Dato y dos Hijos vac´ıos; una modificadora, denominada uni´on, que dados dos ´Arboles Binarios arBinIzq y arbinDer y un Dato x obtiene como resultado un ´Arbol cuya Ra´ız contiene a x y cuyos Hijos son arBinIzq y arbinDer; finalmente, la ´ultima operaci´on B´asica es la t´ıpica consultora que comprueba si un ´Arbol Binario est´a vac´ıo.

2. Operacionesde Recorridocuyo coste es lineal con el N´umero de Nodos del ´Arbol visitados;

en particular, seg´un el orden en que se visitan los Nodos durante un Recorrido se pueden establecer los siguientes tipos:

de Recorrido en Anchura en el que los Nodos se visitan Nivel a Nivel y, dentro de un Nivel, siempre de izquierda a derecha. En base a esta definici´on es claro que la forma m´as natural de describirlas es la iterativa, funci´on que m´as tarde se explicitar´a durante el dise˜no del m´etodo Java imprimirPorNiveles, que a modo de toString obtiene en formato texto el Recorrido en Anchura de los Nodos de un Arbol Binario.´

de Recorridoen Profundidad en el que los Nodos se visitan bajando por las Ramas del ´Arbol y empezando siempre por la situada m´as a la izquierda; es por ello que, al contrario que lo que ocurr´ıa en el Recorrido en Anchura, la forma m´as natural de describirlo es la recursiva. N´otese que el c´alculo del Tama˜no y la Altura de un ´Arbol Binario suponen un Recorrido en Profundidad de ´este, lo mismo que la obtenci´on de la representaci´on en formato texto de sus Nodos (de nuevo toString pero en Profundidad) o la de su copia o la de su imagen sim´etrica o ...

Teniendo en cuenta que un Nodo se identifica con el ´Arbol del que es Ra´ız, seg´un la naturaleza de la operaci´on a realizar cada Nodo puede ser visitado durante un Recorrido en Profundidad de cualquiera de las tres formas siguientes: bienantesque los Hijos Izquierdo y Derecho oen Pre-Orden, bien despu´es que ´estos o en Post- Orden, bien despu´es que el Hijo Izquierdo yantes que el Derecho o en In-Orden.

Conviene mencionar ahora que tambi´en son posibles los Recorridos en Profundidad sim´etricos a los tres indicados, i.e. en los que se visita primero el Hijo Derecho y despu´es el Izquierdo.

Aplicando las definiciones de los cuatro tipos de Recorrido expuestos al ´Arbol Binario que muestra la siguiente figura,

B

A

C

F G

I

D E

H

J K

las diferentes secuencias de Nodos que se visitan durante cada uno de ellos son:

(8)

en In-Orden: D-B-E-H-A-F-C-J-I-K-G en Pre-Orden: A-B-D-E-H-C-F-G-I-J-K en Post-Orden: D-H-E-B-F-J-K-I-G-C-A Por Niveles: A-B-C-D-E-F-G-H-I-J-K

Es m´as, n´otese que si en lugar de Caracteres el ´Arbol Binario representa una expresi´on aritm´etica, sus Recorridos en In-Orden, Pre-Orden y Post-Orden corresponden, respec- tivamente, a las notaciones Infija, Prefija y Postfija de dicha expresi´on.

Cuesti´on:utilizando como ´Arbol ejemplo el que se acaba de mostrar, determ´ınese qu´e tipo de Recorrido en Profundidad requieren el c´alculo de su Altura, Tama˜no y la obtenci´on de un duplicado de ´el o copia.

1.3. Representaci´ on Contigua de un ´ Arbol Binario Completo

Como ya se ha indicado, un ´Arbol Binario Completo es un tipo especial de ´Arbol Binario pues en ´el los Datos de una Colecci´on se distribuyen de forma equilibrada. Adem´as de esta caracter´ıstica, se presenta en esta secci´on una propiedad igualmente importante, estructural, que ser´a utilizada en el siguiente tema para realizar la Implementaci´on eficiente de la EDA Cola de Prioridad: para representar un ´Arbol Binario Completo sin ambig¨uedad alguna basta con almacenar el resultado de su Recorrido por Niveles en un array.

21 16

31

24 19

65 26 32

13

1

2 3

4 5 6 7

8 9 10

1 2 3 4 5 6 7 8 9 10

0

13 21 16 24 31 19 68 65 26 32

68

Espec´ıficamente, como muestra la figura, el Dato que ocupa la Ra´ız del ´Arbol se sit´ua en la posici´on 1 del array (la cero se deja libre por motivos que se explicar´an m´as tarde), el primer Dato del primer Nivel en la 2, el segundo Dato del primer Nivel en la 3 y as´ı sucesivamente hasta que situar el ´ultimo Dato, el N-´esimo si N es el Tama˜no del ´Arbol, del Nivel H, el ´ultimo si H es la Altura del ´Arbol.

Con una Representaci´on como la descrita, que recibe el nombre de Impl´ıcita, no se necesita espacio adicional alguno para representar los dos Hijos del ´Arbol, s´olo el del array que almacena sus Datos y un ´ındice que indica su talla actual. En efecto, si la i-´esima componente del array, 1 ≤ i ≤ N, representa el i-´esimo Nodo (Ra´ız) de su Recorrido por Niveles entonces:

su Hijo Izquierdo se encuentra en la posici´on 2 ∗ i, siempre que 2 ∗ i ≤ N;

su Hijo Derecho se encuentra en la posici´on 2 ∗ i + 1, si 2 ∗ i + 1 ≤ N;

su Nodo Padre est´a en la posici´on i2 si i = 1, ya que la Ra´ız del ´Arbol es el ´unico Nodo que no tiene Padre; si lo tuviera, ocupar´ıa la posici´on cero del array, por lo que, precisamente, ´esta debe dejarse libre.

Adem´as de su destacada eficiencia, una ventaja adicional de la Representaci´on Impl´ıcita es que simplifica las operaciones de Recorrido del ´Arbol.

(9)

1.4. Representaci´ on Enlazada de un ´ Arbol Binario General: el concepto de Nodo Binario

Como ya se ha indicado, la definici´on recursiva de un ´Arbol Binario permite identificar cualquiera de sus Nodos con los (sub) ´Arboles Binarios de los que son Ra´ız; de donde resulta directo establecer que un ´Arbol Binario General sea representado ´unicamente mediante un Enlace a su Nodo Ra´ız. Para que la identificaci´on sea completa y congruente, la Representaci´on de un Nodo Binario, es decir de un Nodo de un ´Arbol Binario, debe constar de tres elementos:

un Objeto que representa el Dato que en ´el se sit´ue y un Enlace al Nodo Binario que es Ra´ız de su Hijo Izquierdo y otro al Nodo Binario Ra´ız de su Hijo Derecho, como se muestra en la siguiente figura:

dato NodoBinario

izq der

Figura 3: Estructura de un Nodo Binario

N´otese que mientras los Nodos de una Lista Enlazada Indirecta s´olo contienen un Enlace al siguiente, una Representaci´on Enlazada de un ´Arbol Binario requiere dos Enlaces, tantos como Hijos tiene el ´Arbol que representa.

2. Implementaci´ on en Java de un ´ Arbol Binario General

A partir de las operaciones y Representaci´on definidas previamente, en esta ´ultima secci´on se desarrollan las dos clases Java que implementan un ´Arbol Binario General: ArbolBinario y NodoBinario. Mientras que la primera se declarar´a p´ublica, por si se quisiera utilizar a- posteriori en aplicaciones t´ıpicas de los ´Arboles Binarios, la segunda es s´olo friendly pues, como se recordar´a, s´olo debe resultar visible a las clases que se desarrollar´an en temas posteriores como posibles implementaciones de los Modelos Avanzados Cola de Prioridad y Diccionario;

ambas se ubicar´an en el paquete jerarquicos del proyecto estructurasDeDatos de libJava.

2.1. La clase ArbolBinario

La clase Java ArbolBinario que se presenta a continuaci´on representa un ´Arbol Binario General mediante un ´unico Enlace a su Nodo Binario Ra´ız; por ello consta de un ´unico atributo NodoBinario raiz sobre el que la gran mayor´ıa de sus m´etodos (tamanyo, altura, etc.) se limitan a lanzar o invocar el correspondiente m´etodo de NodoBinario.

Adem´as de su simplicidad, resulta conveniente se˜nalar dos detalles m´as presentes en la codificaci´on de los m´etodos de ArbolBinario. En primer lugar, obs´ervese que la instrucci´on principal de su m´etodo unir, raiz = new NodoBinario(x, arBin1.raiz, arBin2.raiz), no se llega a ejecutar si los sub ´Arboles par´ametro arBin1 y arBin2 son iguales; si lo son, se lanza y propaga la Excepci´on UnionNoPermitida. Adem´as, en caso de ejecutarse se evita el posible aliasing entre dichos sub ´Arboles par´ametro y los Hijos del ´Arbol resultado de la uni´on:

si no se ejecutase arBin1.raiz = null cuando arBin1 != null, tanto arbin1.raiz como this.raiz.izq apuntar´ıan al mismo Nodo, lo mismo que arbin2.raiz y this.raiz.der si no

(10)

se ejecutara arBin2.raiz = null cuando arBin2 != null. En segundo lugar, los m´etodos de Recorrido siguen dos estilos de dise˜no distintos al lanzar el m´etodo hom´onimo de NodoBinario:

tamanyo, altura y duplicar lo hacen invocando a un m´etodo est´atico mientras que los distintos imprimir invocan a un m´etodo din´amico; como se puede observar ahora, y tambi´en en su implementaci´on en NodoBinario, la ´unica diferencia entre ambos tipos de m´etodos radica en c´omo tratan el caso de un Nodo o (sub) ´Arbol vac´ıo.

package jerarquicos;

import excepciones.*;

public class ArbolBinario { protected NodoBinario raiz;

public ArbolBinario() { raiz = null;}

public ArbolBinario(Object x) { raiz = new NodoBinario(x);}

public void unir(Object x, ArbolBinario arBin1, ArbolBinario arBin2) throws UnionNoPermitida {

if( arBin1.raiz == arBin2.raiz && arBin1.raiz != null )

throw new UnionNoPermitida("Los dos sub´Arboles son iguales; uni´on imposible !!!");

this.raiz = new NodoBinario( x, arBin1.raiz, arBin2.raiz );

/** Para evitar el aliasing, desreferenciar los sub´Arboles utilizados en la uni´on */

if( this != arBin1 ) arBin1.raiz = null;

if( this != arBin2 ) arBin2.raiz = null;

}

public boolean esVacio() { return ( this.raiz == null ); } public int tamanyo() { return NodoBinario.tamanyo(raiz);}

public int altura() { return NodoBinario.altura(raiz); } public void duplicar(ArbolBinario original){

if ( original.raiz != null ) this.raiz = original.raiz.duplicar();

}

public String imprimirPostOrden(){

if ( this.raiz != null ) return raiz.imprimirPostOrden(); else return "*";

}

public String imprimirPreOrden(){

if ( this.raiz != null ) return raiz.imprimirPreOrden(); else return "*";

}

public String imprimirInOrden(){

if ( this.raiz != null ) return raiz.imprimirInOrden(); else return "*";

}

public String imprimirPorNiveles(){

if ( this.raiz != null ) return raiz.imprimirPorNiveles(); else return "*";

} }

2.2. La clase NodoBinario

La clase Java NodoBinario representa un Nodo de un ´Arbol Binario, por lo que sus atributos ser´an tres (seg´un muestra la Figura 3): Object dato, que representa el Dato (de tipo gen´erico) que contiene el Nodo y dos Enlaces NodoBinario izq, der que representan, respectivamente, a sus Hijos Izquierdo y Derecho. N´otese tambi´en que en NodoBinario se re-utiliza el software desarrollado para implementar una Cola: el interfaz Cola del paquete modelos y la clase que lo implementa ArrayCola del paquete lineales; la raz´on es que su m´etodo imprimirPorNiveles implementa un Recorrido en Anchura de un Nodo que s´olo se puede realizar iterativamente, y no en base a su descomposici´on recursiva. Para ello, como ejemplifica el c´odigo propuesto, se debe utilizar como estructura auxiliar una Cola que inicialmente contiene el Nodo a recorrer por Niveles; mientras queden elementos en ella, el tratamiento que sistem´aticamente recibe su primer elemento o Nodo encolado es: tratar el Dato a ´el asociado, eliminarlo y, si no son

(11)

vac´ıos, encolar sus Hijos empezando por el Izquierdo. Obs´ervese que es al tratar la Cola cuando, indirectamente, se realiza el Recorrido iterativo por Niveles un Nodo.

package jerarquicos;

import modelos.*;

import lineales.*;

final class NodoBinario {

Object dato; NodoBinario izq, der;

NodoBinario(Object x) {this(x, null, null); }

NodoBinario(Object x, NodoBinario izquierdo, NodoBinario derecho) { dato = x; izq = izquierdo; der = derecho;

}

static int tamanyo(NodoBinario actual) { if ( actual == null ) return 0;

else return 1 + tamanyo(actual.izq) + tamanyo(actual.der);

}

static int altura(NodoBinario actual) { if ( actual == null) return -1;

else return (Math.max(altura(actual.izq), altura(actual.der)) + 1);

}

NodoBinario duplicar(){

NodoBinario raiz = new NodoBinario(this.dato);

if( this.izq != null ) raiz.izq = this.izq.duplicar( );

if( this.der != null ) raiz.der = this.der.duplicar( );

return raiz;

}

String imprimirPostOrden(){

String res = "";

if( this.izq != null ) res += izq.imprimirPostOrden( );

if( this.der != null ) res += der.imprimirPostOrden( );

res += dato.toString()+"\n";

return res;

}

String imprimirInOrden(){

String res = "";

if( this.izq != null ) res += this.izq.imprimirInOrden( );

res += dato.toString()+"\n";

if( this.der != null ) res += this.der.imprimirInOrden( );

return res;

}

String imprimirPreOrden(){

String res = dato.toString()+"\n";

if( this.izq != null ) res += this.izq.imprimirPreOrden( );

if( this.der != null ) res += this.der.imprimirPreOrden( );

return res;

}

String imprimirPorNiveles(){

String res = "";

Cola q = new ArrayCola();

q.encolar(this);

while ( !q.esVacia() ){

NodoBinario nodoActual = (NodoBinario)(q.desencolar());

res += nodoActual.dato.toString()+"\n";

if ( nodoActual.izq != null ) q.encolar(nodoActual.izq);

if ( nodoActual.der != null ) q.encolar(nodoActual.der);

}

return res;

} }

(12)

Ejercicios propuestos:

1. Se desean a˜nadir a la clase ArbolBinario nuevos m´etodos para realizar las siguientes operaciones:

obtener el n´umero de Hojas de un ´Arbol Binario;

obtener el ´Arbol Binario que es la imagen especular de uno dado;

visualizar la informaci´on asociada a los Nodos del Nivel k de un ´Arbol Binario;

comprobar si alg´un Nodo de un ´Arbol Binario contiene un Objeto dado x;

obtener el Nivel en el que est´a el Nodo que contiene un Objeto dado x.

Dis´e˜nense como invocaciones a sus hom´onimos de NodoBinario, est´aticos o din´amicos seg´un resulte m´as conveniente.

2. Modif´ıquese el m´etodo imprimirPorNiveles() de ArbolBinario para que muestre en l´ıneas diferentes los Nodos de cada Nivel.

3. Implem´entense de forma iterativa los m´etodos imprimirPreOrden(), imprimirInOrden() y imprimirPostOrden() de ArbolBinario.

4. Dis´e˜nese un m´etodo que obtenga el Padre de un Nodo de un ´Arbol Binario e ind´ıquese su coste Temporal ¿Se podr´ıa simplificar modificando la estructura de los Nodos?

Referencias

Documento similar

Más que los programas tradicionales de liderazgo, responder estas tres preguntas determinará tu efectividad como líder del siglo XXI.. Son mujeres y hombres que no

Pero además, me gustaría que fuese un lugar de atracción para los turistas ex- tranjeros, y para ello tengo varias ideas para organizar circuitos turísticos del centro histórico y

Després d’una dècada, es torna a reeditar esta en- tranyable història sobre l’amistat i la natura, ideal per als lectors més menuts (entre els 8 i els 12 anys).. Un llibre, a més

1. LAS GARANTÍAS CONSTITUCIONALES.—2. C) La reforma constitucional de 1994. D) Las tres etapas del amparo argentino. F) Las vías previas al amparo. H) La acción es judicial en

Para conectar a cumplir con tres meses de reciclaje local de anfibios como de vapor de ser efectuado lejos de control distinto al reducir barreras visuales entre albergues para

 Genesis 1:26-28 Entonces dijo Dios: Hagamos al hombre a nuestra imagen, conforme a nuestra semejanza; y señoree en los peces del mar, en las aves de los cielos, en

“⇒” Si AX = B es compatible determinado, A es equivalente por filas a una matriz escalonada reducida cuyo número de pivotes coincide con el número de incógnitas, es decir, A

Es de sobra sabido que el es- píritu movilizador del Estado de Derecho, en toda Europa y durante los últimos doscientos cincuenta años, ha sido la garantía de la libertad frente a