Soluciones del Primer Parcial de Programacion 2 – 26/05/2003

Anuncio
Soluciones del Primer Parcial de Programacion 2 – 26/05/2003
Ejercicio 1
Parte a)
PROCEDURE DelFront(VAR cn: LDNat);
(*Elimina el primer elemento de la Lista con Dos Extemos de Naturales,
dando la baja física al nodo que lo contenía. Precondición: la Lista no es
vacía.*)
VAR aux: PtrNodo;
BEGIN
IF (cn.ultimo = cn.primero) THEN
cn.ultimo := NIL
END;
aux := cn.primero;
cn.primero := cn.primero^.sig;
DISPOSE(aux)
END DelFront;
PROCEDURE DelBack(VAR cn: LDNat);
(* Elimina último elemento de la Lista con Dos Extemos de Naturales, dando
la baja física al nodo que lo contenía. Precondición: la Lista no es
vacía.*)
VAR ult, rec: PtrNodo;
BEGIN
ult:= cn.ultimo;
IF (cn.primero = cn.ultimo) THEN
cn.primero:= NIL;
cn.ultimo:= NIL
ELSE
rec:= cn.primero;
WHILE (rec^.sig # ult) DO
rec := rec^.sig
END;
rec^.sig:= NIL;
cn.ultimo:= rec
END;
DISPOSE(ult)
END DelBack;
Parte b)
PROCEDURE Diferencia(cn1,cn2: LDNat): POINTER TO LDNat;
(* Devuelve una Lista con Dos Extremos de Naturales con los elementos que
pertenecen a cn1 y no pertenecen a cn2. *)
VAR rec1,rec2,rec3,nodo: PtrNodo;
ret : POINTER TO LDNat;
BEGIN
rec1 := cn1.primero;
rec2 := cn2.primero;
NEW(ret);
ret^.primero := NIL;
rec3 := NIL;
WHILE (rec1 <> NIL) DO
WHILE((rec2 <> NIL) AND (rec2^.elem < rec1^.elem)) DO
rec2 := rec2^.sig
END;
IF ((rec2 = NIL) OR (rec1^.elem <> rec2^.elem)) THEN
NEW(nodo);
nodo^.elem := rec1^.elem;
nodo^.sig := NIL;
IF (ret^.primero = NIL) THEN
ret^.primero := nodo
ELSE
rec3^.sig := nodo
END;
rec3 := nodo
END;
rec1 := rec1^.sig
END;
ret^.ultimo := rec3;
RETURN ret
END Diferencia;
Otra version:
PROCEDURE Diferencia_v2(ld1, ld2: LDNat) :POINTER TO LDNat;
VAR
ret: POINTER TO LDNat;
aux, rec1, rec2: PtrNodo;
BEGIN
rec1:=ld1.primero;
rec2:=ld2.primero;
NEW(ret);
ret^.primero:=NIL;
ret^.ultimo:=NIL;
WHILE (rec1<>NIL) AND (rec2<>NIL) DO
IF (rec1^.elem < rec2^.elem) THEN
NEW(aux);
aux^.elem:=rec1^.elem;
aux^.sig:=NIL;
IF (ret^.ultimo=NIL) THEN
ret^.primero:=aux;
ELSE
ret^.ultimo^.sig:=aux;
END;
ret^.ultimo:=aux;
rec1:=rec1^.sig;
ELSIF (rec1^.elem = rec2^.elem)
rec1:=rec1^.sig;
ELSE
rec2:=rec2^.sig;
END;
END; (*primer while*)
WHILE (rec1<>NIL) DO
NEW(aux);
aux^.elem:=rec1^.elem;
aux^.sig:=NIL;
IF (ret^.ultimo=NIL) THEN
ret^.primero:=aux;
ELSE
ret^.ultimo^.sig:=aux;
END;
ret^.ultimo:=aux;
rec1:=rec1^.sig;
END; (*segundo while*)
END Diferencia_v2;
Parte c) Una posibilidad es el doble encadenamiento, en ese caso la representación de la Lista de
Naturales sería:
TYPE PtrNodo = POINTER TO Nodo;
Nodo = RECORD
elem: CARDINAL;
sig, ant: PtrNodo;
END;
LDNat = RECORD
primero: PtrNodo;
ultimo: PtrNodo;
END;
Parte d)
PROCEDURE InsBeforeLast (x: CARDINAL; VAR cn: LDNat);
(* Inserta un elemento en el penúltimo lugar de la Lista con Dos Extemos
de Naturales. Precondición: la Lista no es vacía. *)
VAR nuevo: PtrNodo;
BEGIN
NEW(nuevo);
nuevo^.elem:= x;
nuevo^.sig:= cn.ultimo;
nuevo^.ant:= cn.ultimo^.ant;
cn.ultimo^.ant:= nuevo;
IF (cn.ultimo = cn.primero) THEN
cn.primero:= nuevo
ELSE
nuevo^.ant^.sig:= nuevo
END
END InsBeforeLast;
Ejercicio 2
Parte a)
1. Retorna verdadero si el árbol es completo y de altura o profundidad k, se puede ver que todas las ramas del
árbol son de largo k.
2. Dado que el árbol es binario, completo y de altura k, la cantidad de nodos que tiene es 2k-1.
Justificación:
Pensando el problema de una forma recursiva, tenemos que la cantidad de hojas de un árbol binario
completo de altura k es el doble que las de un árbol de altura k-1 (dado que por cada hoja se tienen dos más).
Por lo tanto podríamos definir una función hojas que sería de la forma:
hojas(1) = 1
hojas(k) = 2 * hojas(k-1)
De esta forma la cantidad de nodos de un árbol de altura k sería igual a la cantidad de nodos del árbol de
altura k-1 más sus hojas. Definiendo la función:
cant(1) = 1
cant(k) = cant(k-1) + hojas(k)
Entonces el resultado de cant(k) para k= 1, 2, 3, etc. es:
k=1
cant(1) = 1
k=2
cant(2) = cant(1) + hojas(2) = 1 + hojas(1) * 2 = 1 + 1 * 2
k=3
cant(3) = cant(2) + hojas(3) = 1 + 1*2 + hojas(2)*2 = 1 + 1*2 + 1*2*2
0
k cualquiera (dado que 1=2 )
i
k
k
cant(i) = (i=0..k-1) 2 = (1-2 ) / (1-2) = 2 -1
Parte b)
PROCEDURE CopiaAcotada (k: CARDINAL; ab: AB): AB
(*Retorne una copia completamente nueva del árbol, de profundidad a lo
sumo k, accediendo directamente a la representación *)
VAR nuevo: AB;
BEGIN
IF (k=0) OR (ab=NIL) THEN
RETURN NIL
ELSE
NEW(nuevo);
nuevo^.info:= ab^.info;
nuevo^.left:= CopiaAcotada(k-1,ab^.left);
nuevo^.right:= CopiaAcotada(k-1,ab^.right);
RETURN nuevo;
END;
END CopiaAcotada;
Ejercicio 3:
Parte a)
PROCEDURE Sufijos(l: LCar):LGCar;
BEGIN
IF Empty(l) THEN
RETURN ConsLG(Null(),NullLG())
ELSE
RETURN ConsLG(l,Sufijos(Tail(l)))
END
END Sufijos;
Parte b)
Una forma de solucionar el problema es insertando al principio de todas las listas generadas por el siguiente
paso de la recursión (que se realiza con el resto de la lista) el primer elemento de la lista. Se debe agregar
también la lista vacía, ya que la misma es prefijo de cualquier tira.
De esta manera, si tenemos la tira “abc”, lo que hacemos es:
 obtener el resultado de Prefijos de “bc” --> {“”,”b”,”bc”}
 insertar ‘a’ en todas las listas --> {“a”,”ab”,”abc”}
 agregar la lista vacía --> {“”,“a”,”ab”,”abc”}
PROCEDURE Prefijos(l: LCar):LGCar;
BEGIN
IF Empty(l) THEN
RETURN ConsLG(Null(),NullLG())
ELSE
RETURN ConsLG(Null(),Insall(Head(l),Prefijos(Tail(l))))
END
END Prefijos;
PROCEDURE Insall(x: CARDINAL;lg: LGCar):LGCar;
BEGIN
IF EmptyLG(lg) THEN
RETURN NullLG()
ELSE
RETURN ConsLG(Cons(x,HeadLG(lg)),Insall(x,TailLG(l)))
END
END Prefijos;
También se puede resolver el problema de una forma análoga a la solución de Sufijos, con la diferencia de que
en este caso la recursión se realiza con la lista resultante de quitar el último elemento a la lista original y no el
primero.
PROCEDURE Prefijos(l: LCar):LGCar;
BEGIN
IF Empty(l) THEN
RETURN ConsLG(Null(),NullLG())
ELSE
RETURN ConsLG(l,Prefijos(SacarUltimo(l)))
END
END Sufijos;
PROCEDURE SacarUltimo(l: LCar):LGCar;
BEGIN
IF (Empty(l)) THEN
RETURN l
ELSIF (Empty(Tail(l)) THEN
RETURN Null()
ELSE
RETURN Cons(Head(l),SacarUltimo(Tail(l)))
END
END SacarUltimo;
Descargar