Instituto de Computación. Facultad de Ingeniería. Universidad de la República Parcial de Programación 2 9 de Mayo de 2009 Generalidades: • • • • • • • • La prueba es individual y sin material La duración es 3hs 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. TENER EN CUENTA LAS NOTAS AL PIE DE CADA EJERCICIO Ejercicio 1 (8 puntos (a) + 12 puntos (b)) Considere la siguiente declaración, en Módula-2, del tipo LBin de las listas que toman valores en {0,1}, que representan números en base 2: Bin = [0..1]; LBin = POINTER TO NodoListaBin; NodoListaBin = RECORD digito : Bin; sig : LBin END; Los números binarios en esta representación tienen los dígitos de menor a mayor orden, de izquierda a derecha. Es decir, que al final de la lista se encuentra el dígito más significativo (el de mayor orden) y al principio el menos significativo (el de menor orden). Ejemplos: Lista de tipo LBin [1] [0,1] [0,1,0,0,1] Número que representa en base 2 1 10 10010 Número que representa en base 10 1 0+2*(1) = 2 0 + 2*(1 + 2*(0 + 2*(0 + 2*(1)))) = 18 Se pide implementar las siguientes operaciones iterativas, accediendo directamente a la representación. a) BinADec, que dada una lista L de tipo LBin, no vacía, devuelve el valor que representa L en notación decimal, sin modificar L. PROCEDURE BinADec (L : LBin) : CARDINAL; (* Precondición: lista no vacía *) Tener en cuenta que si [x1,x2,…xn] es la representación de un número binario, donde x1 es el dígito de menor orden y xn el de mayor orden, el número en notación decimal se puede calcular como: Decimal([x1,x2,…xn]) = x1 + 2*Decimal([x2,…xn]) = …. b) Suma1, que dada una lista L1 de tipo LBin, no vacía, deja en L2 el mismo número en base 2 al que se le ha sumado una unidad (1). PROCEDURE Suma1 (VAR L : LBin); (* Precondición: lista no vacía *) Ejemplos: Entradas L = [1] L = [0,1] L = [1,1] L = [1,1,1,0,1,0,0,1] Resultado de Suma1 L = [0,1] L = [1,1] L = [0,0,1] L = [0,0,0,1,1,0,0,1] NOTAS (para las partes a y b): • Las operaciones no deberán recorrer más de una vez la lista parámetro. • No pueden usarse funciones o procedimientos auxiliares. • Las listas no deben usar celdas dummy (cabeceras). Ejercicio 2 (12 puntos + 8 puntos) Considere las siguientes declaraciones, en Módula-2, del tipo de los árboles binarios de búsqueda de enteros, de tipo ABB, y del tipo de los árboles binarios de pares de números naturales, de tipo ABPar: ABB = POINTER TO ABBNode; ABPar = POINTER TO ABParNode; ABBNode = RECORD dato : INTEGER; izq : ABB; der : ABB; END; ABParNode = RECORD CantIzq : CARDINAL; CantDer : CARDINAL; izq : ABPar; der : ABPar; END; Se pide implementar las siguientes funciones recursivamente, accediendo directamente a la representación y sin usar operaciones auxiliares propias: a) Anotar, que dado un árbol A de tipo ABB, devuelve otro árbol estructuralmente igual a A que contiene en cada nodo un par de naturales que indican cuántos nodos hay a su izquierda (CantIzq) y cuántos a su derecha (CantDer). Ejemplo: 5 3,6 2 1 Anotar 9 3 6 7 10 8 2,0 0,1 15 cantIzq = 3 3,2 0,0 0,0 1,1 cantDer = 2 0,1 0,0 0,0 Si el árbol es vacío, la función debe retornar el árbol vacío. PROCEDURE Anotar (A : ABB) : ABPar; b) MaxDesBalanceo, que dado un árbol de tipo ABPar con anotaciones (obtenidas a partir de la ejecución de la función Anotar sobre un árbol de tipo ABB) devuelve el desbalanceo máximo para todos los nodos del árbol. El desbalanceo de un nodo n es la diferencia entre la cantidad de nodos en los subárboles izquierdo y derecho de n. En el ejemplo de arriba, el máximo desbalanceo es de 3 y se da en la raíz del árbol. PROCEDURE MaxDesBalanceo (AAnot : ABPar) : CARDINAL; (* Precondición: el árbol no es vacío.*) SOLUCIONES: Ejercicio 1) Parte a) PROCEDURE BinADec (L : LBin) : CARDINAL; VAR result, exp: CARDINAL; BEGIN result := 0; exp := 1; (* Se recorren dígitos de menor a mayor orden *) WHILE (L <> NIL) DO IF (L^.digito <> 0) THEN result := result + exp END; exp := exp * 2; L := L^.sig; END; RETURN result; END BinADec; Ejercicio 1) Parte b) PROCEDURE Suma1 (VAR L : LBin); (* L puede pasarse tanto por copia como por referencia *) VAR nodo, Lrec : LBin; BEGIN Lrec := L; WHILE (Lrec.sig <> NIL) AND (Lrec^.digito = 1) DO Lrec^.digito := 0; Lrec := Lrec^.sig; END; IF (Lrec.sig <> NIL) OR (Lrec^.digito = 0) THEN Lrec^.digito := 1; ELSE Lrec^.digito := 0; NEW(nodo); nodo^.digito := 1; nodo^.sig := NIL; Lrec^.sig := nodo; END; END Suma1; Ejercicio 2) Parte a) PROCEDURE Anotar (A : ABB): ABPar; VAR AAnot : ABPar; BEGIN IF (A = NIL) RETURN NIL; ELSE NEW(AAnot); AAnot^.izq := Anotar(A^.izq); AAnot^.der := Anotar(A^.der); IF (A^.izq <> NIL) THEN AAnot^.CantIzq := (AAnot^.izq)^.CantIzq + (AAnot^.izq)^.CantDer + 1; ELSE AAnot^.CantIzq := 0; END; IF (A^.der <> NIL) THEN AAnot^.CantDer := (AAnot^.der)^.CantIzq + (AAnot^.der)^.CantDer + 1; ELSE AAnot^.CantDer := 0; END; RETURN AAnot; END; END Anotar; Ejercicio 2) Parte b) PROCEDURE MaxDesBalanceo (AAnot : ABPar): CARDINAL; VAR max, dif : INTEGER; BEGIN max := ABS(AAnot^.CantIzq - AAnot^.CantDer); IF (AAnot^.izq <> NIL) THEN dif := MaxDesBalanceo (AAnot^.izq); IF (dif > max) THEN max := dif; END; END; IF (AAnot^.der <> NIL) THEN dif := MaxDesBalanceo (AAnot^.der); IF (dif > max) THEN max := dif; END; END; RETURN max; END MaxDesBalanceo;