Instituto de Computación. Facultad de Ingeniería. Universidad de la República Parcial de Programación 2 7 de Mayo de 2010 Generalidades: • • • La prueba es individual y sin material; la duración es 3 horas; sólo se contestan dudas acerca de la letra de los ejercicios. Escriba las hojas de un sólo lado y con letra clara; comience la solución de cada ejercicio en una nueva hoja; numere cada hoja, indicando en la primera el total; coloque su número de cédula y nombre en cada hoja. SI TODAS LAS RESTRICCIONES EXPLICITADAS DE UN EJERCICIO NO SON CUMPLIDAS POR LA SOLUCIÓN PROPUESTA, EL EJERCICIO TENDRÁ PUNTAJE 0. PRESTAR ATENCIÓN A LAS NOTAS INCLUÍDAS EN CADA EJERCICIO. Ejercicio 1 (10 puntos) Considere la siguiente declaración, en Modula-2, del tipo de las listas de números enteros LInt: TYPE LInt = POINTER TO NodoLista; NodoLista = RECORD info : INTEGER; sig : LInt END; L x1 x2 ... xn Se pide, accediendo directamente a la representación, implementar la siguiente función iterativa: comunes: que dadas dos listas L1 y L2 de enteros de tipo LInt, ordenadas de mayor a menor y sin elementos repetidos, retorna una nueva lista (que no comparte registros de memoria con la lista parámetro) ordenada de menor a mayor, que no posee elementos repetidos y que contiene a los elementos comunes de L1 y L2 (que están en ambas listas). NOTAS: Las listas parámetros no deben modificarse. La función no debe recorrer más de una vez cada lista parámetro. La lista resultado no debe recorrerse. No se permite usar funciones ni procedimientos auxiliares. Ejemplos: Entradas Resultado de comunes L1 = [9,5,4,2,1,0], L2 = [8,6,5,3,2,1] [1,2,5] L1 = [9,5,2,1], L2 = [7,4] [] L1 = [9,5,2,1], L2 = [] [] Ejercicio 2 (10 puntos) Considere la siguiente declaración, en Modula-2, del tipo de las listas doblemente encadenadas de números naturales LDNat: TYPE LDNat = POINTER TO NodoListaD; NodoListaD = RECORD info : CARDINAL; sig : LDNat; ant : LDNat; END; L x1 x2 ... ... xn Se pide, accediendo directamente a la representación, implementar el siguiente procedimiento iterativo: elimPos: que dada una lista L de naturales de tipo LDNat y un número natural p, elimina el elemento que se encuentra en la posición p de L. Asumimos como precondición que la posición p está definida en L, esto es que: 1 ≤ p ≤ largo(L). NOTAS: Las posiciones en la lista comienzan a numerarse a partir de 1. No se permite definir funciones ni procedimientos auxiliares. Deberá liberarse la memoria de la celda cuyo elemento sea eliminado. La lista parámetro no podrá recorrerse más de una vez. Ejemplos: Entradas Resultado de elimPos L = [9,2,4,5,6], p = 3 L = [9,2,5,6] L = [9,2,4,3,6], p = 1 L = [2,4,3,6] L = [8,2,5,1,6], p = 5 L = [8,2,5,1] L = [4], p = 1 L = [] Ejercicio 3 (parte a: 8 puntos y parte b: 12 puntos) Considere la siguiente declaración, en Modula-2, del tipo de los árboles binarios de búsqueda de enteros: ABB = POINTER TO ABNode; ABNode = RECORD raiz : INTEGER; izq : ABB; der : ABB; END; Se pide: A) Implemente un procedimiento recursivo imprimirMenores que, dados un árbol binario de búsqueda de enteros A de tipo ABB (sin elementos repetidos) y un entero x, imprima todos los elementos de A que son menores que x, ordenados de mayor a menor. NOTAS: El procedimiento debe evitar recorrer todo el árbol, si no es estrictamente necesario hacerlo. No se permiten definir procedimientos ni funciones ni estructuras de datos auxiliares. Ejemplo: 8 3 9 2 y x = 5 imprimirMenores 4 3 2 7 4 6 Para el árbol de arriba y x = 1, imprimirMenores no imprime nada. Lo mismos ocurre si el árbol es vacío, independientemente del valor de x. B) Implemente un procedimiento recursivo borrarMayores que dados un árbol binario de búsqueda de enteros A de tipo ABB (sin elementos repetidos) y un entero x, elimine de A todos los elementos mayores a x. El árbol resultado debe ser un árbol binario de búsqueda. NOTAS: Se sugiere usar un procedimiento auxiliar, que deberá ser implementado, que elimine todos los nodos de un árbol, dejando a éste vacío. No se permite definir procedimientos ni funciones auxiliares, además del procedimiento sugerido. Tampoco se pueden definir estructuras de datos auxiliares. No se permite recorrer el árbol más de una vez. Deberá liberarse la memoria de todas las celdas cuyos elementos sean eliminados. Ejemplo: 8 3 9 2 7 y x = 5 borrarMayores 3 2 4 4 6 Para el árbol parámetro de arriba y x = 1, borrarMayores deja al árbol vacío. Notar también que si el árbol está originalmente vacío, el procedimiento no tendrá efecto sobre el mismo, para ningún valor de x. SOLUCIONES Ejercicio 1 PROCEDURE Comunes(L1: LInt; L2: LInt): LInt; (* PRECODICIÓN: L1 y L2 estan ordenadas de mayor a menor y no tienen elementos repetidos *) VAR Lres, nodo: LInt; BEGIN Lres := NIL; WHILE ((L1 <> NIL) AND (L2 <> NIL)) DO IF (L1^.info = L2^.info) THEN NEW(nodo); nodo^.info := L1^.info; nodo^.sig := Lres; Lres := nodo; L1 := L1^.sig; L2 := L2^.sig; ELSIF (L1^.info > L2^.info) THEN L1 := L1^.sig; ELSE L2 := L2^.sig; END; END; RETURN Lres; END Comunes; Ejercicio 2 PROCEDURE elimPos (p: CARDINAL; VAR L: LDNat); (* PRECONDICIÓN: p esta definida en L *) VAR aBorrar: LDNat; BEGIN aBorrar := L; WHILE(p > 1) DO p := p - 1; aBorrar := aBorrar^.sig; END; IF ((aBorrar^.ant = NIL) AND (aBorrar^.sig = NIL)) THEN L := NIL; ELSIF (aBorrar^.ant = NIL) THEN L := aBorrar^.sig; aBorrar^.sig^.ant := NIL; ELSIF (aBorrar^.sig = NIL) THEN aBorrar^.ant^.sig := NIL; ELSE aBorrar^.ant^.sig := aBorrar^.sig; aBorrar^.sig^.ant := aBorrar^.ant; END; DISPOSE(aBorrar); END elimPos; Ejercicio 3 – parte a PROCEDURE imprimirMenores(x: INTEGER; A: ABB); (* PRECONDICIÓN: A es un ABB que no tiene elementos repetidos *) BEGIN IF A <> NIL THEN IF (x <= A^.raiz) THEN imprimirMenores(x, A^.izq); ELSE imprimirMenores(x, A^.der); WriteInt(A^.raiz, 1); WriteString(" "); imprimirMenores(x, A^.izq); END; END; END imprimirMenores; Ejercicio 3 – parte b PROCEDURE borrarNodos(VAR A: ABB); BEGIN IF A <> NIL THEN borrarNodos(A^.izq); borrarNodos(A^.der); DISPOSE(A); END; END borrarNodos; PROCEDURE borrarMayores(x: INTEGER; VAR A: ABB); (* PRECONDICIÓN: A es ABB que no tiene elementos repetidos *) VAR aBorrar: ABB; BEGIN IF A <> NIL THEN IF (x >= A^.raiz) THEN borrarMayores(x, A^.der); ELSE aBorrar := A; A := A^.izq; aBorrar^.izq := NIL; borrarNodos(aBorrar); borrarMayores(x, A); END; END; END borrarMayores;