Solución Examen de Programación 2

Anuncio
Instituto de Computación. Facultad de Ingeniería. Universidad de la República
Solución Examen de Programación 2
Agosto 2005
Considere la siguiente declaración, en MÓDULA-2, del tipo ListaEnt de listas encadenadas de enteros:
ListaEnt = POINTER TO NodoEnt;
NodoEnt = RECORD
info: INTEGER;
sig: ListaEnt;
END;
Implemente en MÓDULA-2 una función F que dadas dos listas ordenadas (en forma ascendente) de enteros,
C1 y C2, y sin elementos repetidos que representan a dos conjuntos, retorne una nueva lista ordenada y sin
elementos repetidos que represente al conjunto (C1-C2)∪(C2-C1).
A tener en cuenta:
• La nueva lista no deberá compartir registros de memoria con las listas parámetros.
• Se requiere que esta función recorra a lo sumo una vez cada lista parámetro.
• No se permite usar TADs auxiliares.
• Si usa funciones o procedimientos auxiliares deberá implementarlos, pero recuerde que cada una de
las listas pueden recorrerse a lo sumo una vez (se usen o no funciones o procedimientos auxiliares).
El cabezal de la función es el siguiente:
PROCEDURE F (C1, C2 : ListaEnt) : ListaEnt;
(* La siguiente función retorna una lista con los elementos exclusivos de cada una de las listas
parámetro, sin compartir memoria con éstas. *)
PROCEDURE F (c1, c2 : CardLista) : CardLista;
VAR
result, iter : CardLista;
BEGIN
NEW (result); (* celda dummy *)
iter := result;
WHILE ((c1 <> NIL) AND (c2 <> NIL)) DO
IF (c1^.info <> c2^.info) THEN
NEW (iter^.sig);
iter := iter^.sig;
IF (c1^.info < c2^.info) THEN
iter^.info := c1^.info;
c1 := c1^.sig
ELSE
iter^.info := c2^.info;
c2 := c2^.sig
END
ELSE
c1 := c1^.sig;
c2 := c2^.sig
END
END;
IF (c1 = NIL) THEN
c1 := c2 (* la lista eventualmente no vacía queda en c1 *)
END;
WHILE (c1 <> NIL) DO
NEW (iter^.sig);
iter := iter^.sig;
iter^.info := c1^.info;
c1 := c1^.sig
END;
iter^.sig := NIL;
iter := result;
result := result^.sig;
DISPOSE (iter); (* se borra la celda dummy *)
RETURN (result)
END F;
Para trabajar con árboles balanceados es útil guardar en cada nodo información para verificar condiciones de
equilibrio. Por ejemplo, en los árboles llamados AVL (que son ABB balanceados) puede guardarse en cada
nodo la altura del árbol que tiene a dicho nodo como raíz.
En la siguiente figura se puede ver un ejemplo de la información que poseen los nodos de esta clase de
árboles:
6
h=2
h=1
h=0
2
h=3
3
9
4
h=0
h=1
10
h=0
1
Se pide, utilizando la siguiente definición de los árboles binarios de búsqueda de enteros, con información de
la altura en cada nodo:
ABB = POINTER TO ABBNodo;
ABBNodo = RECORD
info: INTEGER;
altura: CARDINAL;
izq, der: ABB;
END;
a) Implementar un procedimiento que dado un ABB de enteros que guarda en cada nodo, además del dato, el
valor de su altura, y dado un entero, inserte a dicho elemento en el ABB (si ya no estaba) manteniendo la
información de la altura de cada nodo. Notar que no se pide balancear el árbol, sino simplemente insertar
el elemento en el ABB dejando en cada nodo en el campo altura el valor correspondiente, asumiendo que
el árbol parámetro guarda en el campo altura de cada nodo el valor correcto. Este procedimiento no puede
usar funciones ni procedimientos auxiliares.
b) Implemente una función booleana que retorne TRUE si y sólo si un ABB (del tipo definido
anteriormente) es un AVL. Esto es, se cumple que para cada nodo del árbol la altura de sus subárboles
izquierdo y derecho difiere a lo sumo en 1. El árbol vacío es un AVL. Esta función no puede usar
funciones ni procedimientos auxiliares.
a)
PROCEDURE Insertar (VAR t : ABB; x : INTEGER);
BEGIN
IF (t = NIL) THEN
NEW(t);
t^.info := x;
t^.altura := 0;
t^.izq := NIL;
t^.der := NIL
ELSIF (x < t^.info) THEN
Insertar(t^.izq, x);
IF (t^.altura = t^.izq^.altura) THEN
t^.altura := t^.altura + 1
END
ELSIF (x > t^.info) THEN
Insertar(t^.der, x);
IF (t^.altura = t^.der^.altura) THEN
t^.altura := t^.altura + 1
END
END
END Insertar;
b)
PROCEDURE EsAVL (t : ABB) : BOOLEAN;
BEGIN
IF (t = NIL) OR ((t^.izq = NIL) AND (t^.der = NIL)) THEN
RETURN TRUE
ELSIF (t^.izq = NIL) THEN
RETURN (t^.der^.altura = 0)
ELSIF (t^.der = NIL) THEN
RETURN (t^.izq^.altura = 0)
ELSE RETURN (ABS(t^.izq^.altura – t^.der^.altura) <= 1)
AND EsAVL(t^.izq) AND EsAVL(t^.der)
END
END EsAVL;
Se quiere especificar e implementar, en MÓDULA-2, un TAD ColaDoble que permita insertar y eliminar
elementos (de a uno por vez) al comienzo y al final de una estructura lineal.
Se pide:
a) Especificar, incluyendo pre y postcondiciones, el TAD ColaDoble de elementos de un tipo genérico
adecuado para modelar una estructura lineal no acotada, con operaciones que permitan:
Crear la estructura vacía,
Agregar un elemento al comienzo de la estructura lineal,
Agregar un elemento al final de la estructura lineal,
Verificar si la estructura es vacía,
Eliminar y retornar el elemento al comienzo de la estructura lineal (si la estructura es no vacía),
Eliminar y retornar el elemento al final de la estructura lineal (si la estructura es no vacía),
DEFINITION MODULE ColaDbl;
TYPE CDoble;
(***** Constructoras *****)
PROCEDURE Null (VAR C : CDoble);
(* retorna la cola vacía *)
PROCEDURE EnqueueFront (dato : T; VAR C : CDoble);
(* inserta el dato al inicio de la cola C *)
PROCEDURE EnqueueBack (dato : T; VAR C : CDoble);
(* inserta el dato al final de la cola C *)
(***** Predicado ******)
PROCEDURE IsEmpty (C : CDoble) : BOOLEAN;
(* Retorna TRUE si C es vacía *)
(***** Selectoras *****)
PROCEDURE Front (VAR dato : T; VAR C : CDoble);
(* Pre : C no es vacía
Retorna el elemento que se encuentra al comienzo de la cola C y lo quita de ella *)
PROCEDURE Back (VAR dato : T; VAR C : CDoble);
(* Pre : C no es vacía
Retorna el elemento que se encuentra al final de la cola C y lo quita de ella *)
END ColaDbl.
Desarrollar una estructura para implementar el TAD anterior, sin usar TADs auxiliares, de tal manera que
todas las operaciones se realicen sin recorrer la estructura elegida. Desarrollar el código de las siguientes 3
operaciones: la que crea la estructura vacía; la que elimina y retorna un elemento al final; y la que agrega un
elemento al comienzo. Omita el código del resto de las operaciones del TAD.
La estructura debe contemplar la restricción de que todas sus operaciones se realicen sin necesidad de
recorrerla. Para ello puede ser implementada mediante una lista doblemente encadenada y con apuntadores al
primero y último elemento. De esta forma se permite el acceso al principio y final de la cola sin necesidad de
recorrerla.
IMPLEMENTATION MODULE ColaDbl;
FROM Storage IMPORT ALLOCATE, DEALLOCATE;
TYPE
(* definición de la celda básica de la cola *)
Celda = POINTER TO NCelda;
NCelda = RECORD
info : CHAR; (* información *)
sig : Celda; (* puntero al siguiente *)
ant : Celda (* puntero al anterior *)
END;
(* definición de la celda cabezal de la cola *)
CDoble = POINTER TO NCabezal;
NCabezal = RECORD
primero : Celda; (* puntero a la primera celda *)
ultimo : Celda
(* puntero a la última celda *)
END;
PROCEDURE Null (VAR C : CDoble) ;
BEGIN
(* se crea la celda cabezal *)
NEW(C);
(* se crea una celda dummy *)
NEW(C^.primero);
C^.primero^.sig := NIL;
C^.primero^.ant := NIL;
C^.ultimo := C^.primero
END Null;
PROCEDURE EnqueueFront(dato : T; VAR C : CDoble);
(* agrega un elemento al principio *)
VAR
q : Celda;
BEGIN
(* Crea una celda para contener el nuevo elemento *)
NEW(q);
q^.info := dato;
q^.sig := C^.primero^.sig;
q^.ant := C^.primero;
(* Coloca la nueva celda luego de la celda dummy *)
C^.primero^.sig := q;
(* Se verifica si es el primer elemento que se agrega a la estructura*)
IF C^.ultimo = C^.primero THEN
(* es el único elemento en la estructura entonces se actualiza el puntero al último *)
C^.ultimo := q
ELSE
(* sino, la segunda celda debe apuntar a la nueva celda *)
q^.sig^.ant := q
END
END EnqueueFront;
PROCEDURE Back (VAR dato : T; VAR C : CDoble);
(* Retorna el primer elemento de la cola y lo borra *)
VAR
delete : Celda;
BEGIN
dato := C^.ultimo^.info;
(* se apunta a la última celda, la cual se quierre borrar *)
delete := C^.ultimo;
(* se actualiza el puntero al último *)
C^.ultimo := C^.ultimo^.ant;
C^.ultimo^.sig := NIL;
(* se borra la celda *)
DISPOSE(delete)
END Back;
END ColaDbl.
Descargar