Práctica 8. Implementación de operaciones de la clase Árbol Binario

Anuncio
ESTRUCTURAS DE DATOS Y ALGORITMOS
Escuela Técnica Superior de Informática Aplicada
Curso 2004-2005
Práctica 8. Implementación de operaciones de la clase
Árbol Binario de Búsqueda
Duración: 2 sesiones
1 Objetivo de la práctica
El objetivo de esta práctica es realizar tareas de implementación de estructuras de datos. En
concreto, y partiendo de la clase ArbolBinariodeBusqueda, se tendrá que implementar el
método que resuelva la búsqueda del sucesor de un elemento dado del árbol.
2 Descripción del problema
2.1 Sucesor de un dato en un árbol binario de búsqueda
Supóngase un árbol binario de búsqueda como el de la figura 1.a, en el que sus objetos son
Integer. Considérese el nodo x (que no tiene hijo izquierdo), y la rama del árbol que conduce
desde el nodo raíz hasta x, de cuyos nodos se dirán que son los ascendientes de x. Para cualquier
nodo n de esta rama, se puede observar que:
• si x aparece en su subárbol izquierdo, n.dato>x.dato, y los datos que aparezcan en su
subárbol derecho serán aún mayores que n.dato; se dirá que n es un ascendiente por la
derecha,
• análogamente, si x aparece en su subárbol derecho, n.dato<x.dato, y los datos que
aparezcan en su subárbol derecho serán aún menores que n.dato; se dirá que n es un
ascendiente por la izquierda.
En consecuencia, el menor de los datos del árbol mayores que x.dato, aparece en alguno de los
nodos ascendientes por la derecha de x. Considérese y, el más cercano de ellos a x. Por el mismo
razonamiento, sus nodos ascendientes por la derecha en la rama considerada, contendrán datos
mayores que y.dato. En resumen, y.dato es el siguiente valor a x.dato de entre todos los
contenidos en el árbol.
a)
b)
100
100
>100
50
50
y
<50
y
75
75
>75
52
x
52
x
<52
68
68
<68
71
Figura 1
69
73
Adicionalmente, y redundando en lo anterior, se observa que el nodo y es el siguiente visitado
al nodo x en un recorrido inorden del árbol.
En la variante de la figura 1.b, el nodo x sí tiene subárbol izquierdo no vacío, cuyos nodos
seguirán a x en un recorrido inorden: el mínimo dato encontrado en x.der será el sucesor de
x.dato.
Considérese el ejemplo de la figura 2; el sucesor de 85 y de 100 están en el ascendiente por la
derecha más cercano: el nodo que contiene a 100 y null respectivamente (el sucesor de 100 no
existe). El sucesor de 25 y el de 50 están en el mínimo del respectivo subárbol derecho: nodos con
datos 30 y 60, respectivamente.
100
50
25
10
75
30
60
85
Figura 2
Si en el ejemplo de la figura anterior se considera únicamente la parte del árbol que arranca del
nodo n.izq (figura 3), el sucesor de 85 resulta ahora null.
n
100
n.izq
50
25
10
75
30
60
85
Figura 3
De todo lo anterior, se sigue un método de obtención del sucesor de una cierta clave d, que
admite una sencilla expresión iterativa:
Supuestas unas variables x, ascenDer, de tipo NodoBinario y que respectivamente
referencien al nodo a inspeccionar y a su ascendiente por la derecha más cercano, se irán
actualizando de la forma adecuada estas variables mientras queden nodos por revisar y no se haya
encontrado que x.dato coincida con d. La búsqueda empezará a partir del nodo n que se indique.
El caso en que la búsqueda termine sin encontrar d, se tratará mediante una excepción.
El nodo que se devuelva deberá ser ascenDer o el mínimo de x.der según el caso.
La actividad 3.1 de esta práctica está dedicada a la implementación de esta operación dentro de
la clase ArbolBinarioDeBusqueda.
2
2.2 Incorporación de la operación sucesor al modelo Diccionario
Una de las implementaciones clásicas del modelo Diccionario se basa en los árboles binarios de
búsqueda. En particular, en la práctica 6, se consideró la siguiente organización de clases:
• paquete modelos: contiene, entre otras, la interfaz Diccionario,
• paquete jerarquicos: contiene las clases NodoBinario, ArbolBinarioDeBusqueda, y
ABBDiccionario, entre otras. Esta última implementa la interfaz Diccionario, y para ello
extiende a la clase ArbolBinarioDeBusqueda, de la que se puede decir que concentra el
mayor esfuerzo en el desarrollo de las operaciones.
Considérese la posibilidad de hacer un modelo de Diccionario más extenso que el contemplado
hasta el momento, y que, por ejemplo, incluyese una función para averiguar el elemento sucesor
a una dado. Si la interfaz Diccionario incluye este método, deberá ser implementado por toda
aquella clase que implemente a la interfaz, como es el caso de ABBDiccionario.
En la actividad 3.2 de esta práctica se llevará a cabo esta posibilidad, partiendo del hecho de
que en la clase ArbolBinarioDeBusqueda se ha incluido el método sucesor discutido en el
apartado anterior.
3 Actividades en el laboratorio
3.1 Implementación y prueba de la operación sucesor
Se partirá del fichero ArbolBinarioBusqueda.java, que se añadirá al paquete jerarquicos,
obteniéndolo de /labos/asignaturas/EI/eda/practica7. Se editará esta clase para
añadirle un método con el siguiente perfil:
protected NodoBinario sucesor(Object clave, NodoBinario n)
throws ElementoNoEncontrado
y que, partiendo del subárbol que arranca del nodo n, calculará el nodo cuyo dato coincida con el
sucesor de clave (null en el caso en que clave sea el máximo elemento del subárbol). Si
clave no aparece en el subárbol, se producirá la excepción correspondiente, la cual precisará que
no se ha encontrado el elemento al buscar el sucesor.
La implementación de este método deberá ser iterativa, según las indicaciones del apartado 2.1.
Para probar la corrección del método en el entorno bluej, se sugiere, en primer lugar, crear una
instancia a de la clase ABBDiccionario. Se le insertarán sucesivamente los elementos Integer
100, 50, 25, 75, 10, 30, 60 y 85, para configurar la estructura de la figura 2. Dado que esta clase
habrá heredado el método anterior, se procederá a probar su funcionamiento aplicándolo al objeto
a. Se probarán los casos de búsqueda del sucesor sobre a, partiendo del nodo a.raiz, y
a.raiz.izq, que se detallan en el apartado 2.1.
3.2 Ampliación del modelo Diccionario
Una vez modificada y probada la clase ArbolBinarioDeBusqueda, se accederá al código
fuente de la clase ABBDiccionario en el fichero ABBDiccionario.java, siguiendo la ruta
/labos/asignaturas/EI/eda/practica7/, y depositándolo en el paquete jerarquicos.
Se añadirá a la clase ABBDiccionario un método con el siguiente perfil:
public Object sucesor(Object clave) throws ElementoNoEncontrado
que devolverá el sucesor de clave en el árbol sobre el que se aplique el método.
Para su implementación, se tendrá en cuenta que esta clase hereda el método sucesor de la
clase ArbolBinarioDeBusqueda. Entonces, obtener el objeto sucesor de clave, consistirá en
3
extraer el dato del nodo devuelto por super.sucesor(clave,this.raiz), (null si el
sucesor no existe).
Se incluirá el perfil de este método en la interfaz Diccionario.java del paquete modelos,
para que el cálculo del sucesor se pueda utilizar en las aplicaciones del modelo.
Como una aplicación concreta, se modificará el TestTraductor de la práctica 6 para que entre
sus opciones, aparezca la de buscar las tres entradas sucesoras a una clave dada. Se probará sobre
el diccionario bilingüe que se habrá cargado desde el fichero datos2.txt, accesible también en
la ruta que se menciona más arriba.
4
Descargar