Programación Declarativa Ejercicios de programación con árboles Ejercicio 1 Dada la siguiente representación de árbol binario: ArbolB ::= vacioB | nodoB(ArbolB,Raiz,ArbolB) define los siguientes predicados sobre árboles binarios: es arbolB(A) es arbolB nat(A) raiz(R,A) hoja(H,A) miembro(X,A) padre(X,Y,A) hijo(X,Y,A) descendiente(X,Y,A) ascendiente(X,Y,A) rama(Rs,A) esta(X,A) no esta(X,A) sustituye(X,Y,AX,AY) A es un árbol binario bien formado A es un árbol binario de naturales R es la raı́z de A H es una hoja de A X es elemento de A X es padre de Y en A X es hijo de Y en A X es descendiente de Y en A X es ascendiente de Y en A la lista Rs es una rama de A X está en A (sólo en modo test (+,+)) X no está en A (sólo en modo test (+,+)) AY es AX sustituyendo todas las X por Y Ejercicio 2 Define las siguientes relaciones sobre árboles binarios: subarbol(A,B) simetricos(A,B) isomorfos estruc(A,B) isomorfos ramas(A,B) A A A A es subárbol de B y B son simétricos y B tienen la misma estructura y B tienen las mismas ramas Ejercicio 3 Define versiones recursivas (con y sin acumulador) de los siguientes predicados sobre árboles binarios: num nodos(A,N) profundidad(A,P) maximo(A,M) suma(A,S) frontera(A,Fs) A tiene N nodos P es la profundidad de A M es el máximo de A S es la suma de los nodos de A Fs es la frontera de A Ejercicio 4 Define los siguientes predicados de recorrido sobre árboles binarios: miembro preorden(X,A) generador de elementos de A en preorden preorden(Rs,A) Rs es una lista con el recorrido en preorden de A miembro inorden(X,A) generador de elementos de A en inorden inorden(Rs,A) Rs es una lista con el recorrido en inorden de A miembro postorden(X,A) generador de elementos de A en postorden postorden(Rs,A) Rs es una lista con el recorrido en postorden de A miembro anchura(X,A) generador de elementos de A en anchura anchura(Rs,A) Rs es una lista con el recorrido en anchura de A 1 Ejercicio 5 Define un predicado arbol inorden(Rs,A) tal que, dada una lista Rs, genere todos los árboles binarios A tales que su recorrido en inorden es Rs. Ejercicio 6 Define un predicado construye arbol(Ps,Is,A) que reconstruya un árbol binario A a partir de sus recorridos en preorden Ps e inorden Is. Ejercicio 7 Define un predicado genera arbolB(A) que se comporte como un generador no acotado de árboles binarios. Asegúrate de que no se trate de un generador anómalo. Ejercicio 8 Define un predicado camino(X,A,Cs) que, dado un árbol binario A, se satisfaga si la lista Cs contiene un camino desde la raı́z de A hasta un nodo X. El camino debe almacenar las raices de los nodos que lo componen, ası́ como los lados del árbol por los que se desciende. Por ejemplo: ?- arbol_ejemplo(_A), camino(5,_A,Cs). Cs = [ (4->der), (6->izq), 5] ; No significa que hay un camino en el árbol A que parte de la raı́z 4, desciende por la derecha visitando 6 y desciende por la izquierda hasta llegar al nodo destino 5. Ejercicio 9 Define un predicado camino entre(X,Y,A,Cs) que, dado un árbol binario A, se satisfaga si la lista Cs contiene un camino desde un nodo X hasta un nodo Y. El camino debe almacenar las raices de los nodos que lo componen, ası́ como los lados del árbol por los que se desciende. Por ejemplo: ?- arbol_ejemplo(_A), camino_entre(6,5,_A,Cs). Cs = [(6->izq), 5] ; No significa que hay un camino en el árbol A que parte del nodo 6 y desciende por la izquierda hasta llegar al nodo destino 5. Ejercicio 10 Define un predicado nodos prof i(I,A,Is) que, dados un árbol binario A y un entero positivo I, devuelva una lista Is con los nodos de A situados a profundidad I. Ejercicio 11 Define un predicado por profundidad(A,Iss) que, dado un árbol binario A, devuelva una lista de listas Iss tal que la lista i-ésima contenga los nodos de A situados a profundidad i-ésima. Escribe dos versiones: una que haga uso del predicado nodos prof i(I,A,Is) y otra que no. Ejercicio 12 Se desea representar en Prolog árboles de búsqueda mediante términos de la forma: 2 ArbolBusq ::= vacioBusq | nodoBusq(ArbolBusq,Clave,ArbolBusq) donde no hay claves repetidas, los elementos menores (@<) que Clave están a la izquierda, y los mayores (@>) a la derecha. Define los siguientes predicados sobre árboles de búsqueda: es arbolBusq(A) inserta(X,A,AX) esta(X,A) no esta(X,A) borra(X,AX,A) miembro inorden(X,A) inorden(Rs,A) A es un árbol de búsqueda bien formado AX es el árbol que resulta de insertar X en A X está en A (sólo en modo test (+,+)) X no está en A (sólo en modo test (+,+)) A es el árbol que resulta de borrar X de AX generador de elementos de A en inorden Rs es la lista con el recorrido en inorden de A Ejercicio 13 Define un predicado ordenar(Xs,Ys) que dada una lista Xs devuelva su ordenación en Ys. Utiliza un árbol de búsqueda para ordenar los elementos. Ejercicio 14 Un árbol hoja es un árbol binario no vacı́o que almacena información sólo en las hojas. Los árboles hoja pueden representarse en Prolog por términos de la forma: ArbolH ::= hoja(Dato) | nodoH(ArbolH,ArbolH) define los siguientes predicados sobre árboles hoja: es arbolH(A) es arbolH nat(A) miembro(X,A) esta(X,A) no esta(X,A) sustituye(X,Y,AX,AY) subarbol(A,B) simetricos(A,B) isomorfos estruc(A,B) isomorfos ramas(A,B) num hojas(A,N) profundidad(A,P) maximo(A,M) suma(A,S) frontera(A,Fs) A es un árbol hoja bien formado A es un árbol hoja de naturales X es elemento de A X está en A (sólo en modo test (+,+)) X no está en A (sólo en modo test (+,+)) AY es AX sustituyendo todas las X por Y A es subárbol de B A y B son simétricos A y B tienen la misma estructura A y B tienen las mismas ramas A tiene N hojas P es la profundidad de A M es el máximo de A S es la suma de las hojas de A Fs es la frontera de A Ejercicio 15 Define un predicado camino(X,A,Cs) que, dado un árbol hoja A, se satisfaga si la lista Cs contiene un camino desde la raı́z de A hasta una hoja X. El camino debe almacenar los lados del árbol por los que se desciende hasta llegar a la hoja X. Por ejemplo: 3 ?- arbol_hoja_ejemplo(_A), camino(5,_A,Cs). Cs = [ der, izq, 5] ; No significa que hay un camino en el árbol A que parte de la raı́z y desciende por la derecha y por la izquierda hasta llegar a la hoja destino 5. Ejercicio 16 Define un predicado arbolH frontera(Fs,A) que dada una lista Fs genere todos los árboles hoja A tales que Fs es su frontera Ejercicio 17 Define un predicado genera arbolH(A) que se comporte como un generador no acotado de árboles hoja. Asegúrate de que no se trate de un generador anómalo. Ejercicio 18 Un árbol genérico puede ser vacı́o, lo que representaremos en Prolog mediante la constante vacioG o bien tener una raı́z y un número arbitrario n de hijos (n ≥ 0), representado en Prolog por términos de la forma: ArbolG ::= nodoG(Raiz,[ArbolG]) es decir, cada nodo tiene una raı́z y una lista con sus hijos (los nodos hoja se representarán por términos de la forma nodoG(Raiz,[])). Define los siguientes predicados sobre árboles genéricos: es arbolG(A) es arbolG nat(A) miembro(X,A) esta(X,A) no esta(X,A) sustituye(X,Y,AX,AY) subarbol(A,B) simetricos(A,B) isomorfos estruc(A,B) num nodos(A,N) profundidad(A,P) maximo(A,M) suma(A,S) frontera(A,Fs) A es un árbol genérico bien formado A es un árbol genérico de naturales X es elemento de A X está en A (sólo en modo test (+,+)) X no está en A (sólo en modo test (+,+)) AY es AX sustituyendo todas las X por Y A es subárbol de B A y B son simétricos A y B tienen la misma estructura A tiene N hojas P es la profundidad de A M es el máximo de A S es la suma de los nodos de A Fs es la frontera de A 4