Parcial de Programación 2

Anuncio
Instituto de Computación. Facultad de Ingeniería. Universidad de la República
Parcial de Programación 2
10 de Mayo de 2008
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 CERO. TENER EN CUENTA LAS NOTAS
AL PIE DE CADA EJERCICIO.
Ejercicio 1 (12 puntos)
Considere la siguiente declaración, en Módula-2, del tipo de las listas de números enteros LInt:
TYPE
LInt = POINTER TO NodoLista;
NodoLista = RECORD
info : INTEGER;
sig : LInt
END;
Se pide, accediendo directamente a la representación, implementar la siguiente función iterativa:
InsOrd: Dada una lista L de enteros de tipo Lint, ordenada de mayor a menor, y dado un entero x, retorna una
nueva lista (que no comparte registros de memoria con la lista parámetro) ordenada de menor a mayor que contiene
todos los elementos de L, y además x.
Ejemplos:
Entradas
Resultado de InsOrd
L = [9,9,5,2,1], x = 4
[1,2,4,5,9,9]
L = [9,5,2,1], x = 1
[1,1,2,5,9]
L = [2], x = 3
[2,3]
L = [], x = 1
[1]
NOTAS:
•
•
•
•
•
La lista parámetro no debe modificarse.
La función no debe recorrer más de una vez la lista parámetro. La lista resultado no debe recorrerse.
No se permite usar funciones o procedimientos auxiliares.
Las listas no deben usar celdas dummy (cabeceras).
Pueden declararse y usarse a lo sumo dos variables auxiliares en el código de la función insOrd.
SOLUCIÓN:
PROCEDURE InsOrd (L : LNat; x : CARDINAL) : LNat;
VAR nodo, Lres : LNat;
BEGIN
Lres := NIL;
(* Copio los elementos de L mayores que a x *)
WHILE (L <> NIL) AND (L^.elem > x) DO
NEW(nodo);
nodo^.elem := L^.elem;
nodo^.sig := Lres;
Lres := nodo;
L := L^.sig;
END;
(* Inserto x *)
NEW(nodo);
nodo^.elem := x;
nodo^.sig := Lres;
Lres := nodo;
(* Copio los elementos de L menores o iguales a x *)
WHILE (L <> NIL) DO
NEW(nodo);
nodo^.elem := L^.elem;
nodo^.sig := Lres;
Lres := nodo;
L := L^.sig;
END;
RETURN Lres;
END InsOrd;
Ejercicio 2 (12 puntos)
Considere las siguientes operaciones sobre Listas de Naturales (Cardinales):
•
PROCEDURE Nula() : LN;
(* Crea la lista de naturales vacía. *)
•
PROCEDURE Agregar (x : CARDINAL; VAR l : LN);
(* Inserta un elemento al principio de la lista de naturales. *)
•
PROCEDURE EsNula (l : LN) : BOOLEAN;
(* Verifica si la lista de naturales está vacía. *)
•
PROCEDURE Primero (l : LN) : CARDINAL;
(* Retorna el primer elemento de la lista de naturales. Precondición: la lista no es vacía.*)
•
PROCEDURE Cola (VAR l : LN);
(* Elimina de la lista de naturales l su primer elemento. Precondición: la lista no es vacía.*)
Se pide: implementar una función recursiva ElimUlt, que dada una lista L de tipo LN elimine y retorne de L su
último elemento. La función debe eliminar todas las ocurrencias del último elemento. ElimUlt tiene como
precondición que L no es la lista vacía.
PROCEDURE ElimUlt (VAR L : LN) : CARDINAL;
Ejemplos:
Entrada
Resultado de ElimUlt
L = [2,8,6,8,8]
L = [2,6], retorna: 8
L = [6,2,3]
L = [6,2] , retorna: 3
L = [2,2]
L = [], retorna: 2
NOTAS:
•
•
•
La función no debe recorrer la lista de manera explícita más de una.
No se permite usar funciones o procedimientos auxiliares, aunque si pueden utilizarse las 5 operaciones
primitivas dadas sobre listas de tipo LN. De hecho, no puede asumirse una representación particular de listas de
tipo LN, la única manera de manipularlas es a través de las 5 operaciones referidas.
No pueden definirse estructuras de datos adicionales a la lista de tipo LN.
SOLUCIÓN:
PROCEDURE ElimUlt (VAR L : LNat) : CARDINAL;
VAR prim, ult : CARDINAL;
BEGIN
prim := Primero(L);
Cola(L);
IF (EsNula(L)) THEN
ult := prim;
ELSE
ult := ElimUlt(L);
IF (prim <> ult) THEN
Agregar(prim, L);
END;
END;
RETURN ult;
END ElimUlt;
Ejercicio 3 (16 puntos: 10 parte a y 6 parte b)
Considere la siguiente declaración, en Módula-2, del tipo de los árboles binarios de búsqueda de enteros:
ABB = POINTER TO ABNode;
ABNode = RECORD
dato
izq
der
END;
: INTEGER;
: ABB;
: ABB;
Se pide implementar las siguientes operaciones recursivamente, accediendo directamente a la representación:
a) Función BorrarMin: Dado un árbol binario de búsqueda de enteros de tipo ABB, elimina y retorna el mínimo
elemento del árbol. Precondición: el árbol es no vacío.
PROCEDURE BorrarMin (VAR A : ABB) : INTEGER;
b) Procedimiento Borrar: Dado un árbol binario de búsqueda de enteros de tipo ABB, elimina el elemento que se
encuentra en la raíz del árbol. Precondición: el árbol es no vacío.
PROCEDURE Borrar (VAR A : ABB);
NOTAS:
•
•
•
•
En ambas operaciones el árbol resultado debe ser binario de búsqueda y tiene que liberarse la memoria de la
celda cuyo elemento sea eliminado.
BorrarMin debe evitar recorrer nodos innecesarios del árbol.
No pueden usarse funciones o procedimientos auxiliares, excepto para el procedimiento Borrar, que sólo
puede eventualmente usar BorrarMin.
Borrar no debe recorrer el árbol (aunque si puede recorrerlo BorrarMin).
SOLUCIONES:
PROCEDURE BorrarMin (VAR A : ABB): CARDINAL;
VAR aBorrar : ABB; min : CARDINAL;
BEGIN
IF (A^.izq = NIL) THEN
aBorrar := A;
min := A^.dato;
A := A^.der;
DISPOSE(aBorrar);
ELSE
min := BorrarMin(A^.izq);
END;
RETURN min;
END BorrarMin;
PROCEDURE Borrar (VAR A : ABB);
BEGIN
IF (A^.der = NIL) THEN
aBorrar := A;
A := A^.izq;
DISPOSE(aBorrar);
ELSE
A^.dato := BorrarMin(A^.der);
END;
END Borrar;
Descargar