Solución Parcial de Programación 2

Anuncio
Instituto de Computación. Facultad de Ingeniería. Universidad de la
República
Solución Parcial de Programación 2
11 de Mayo 2004
Ejercicio 1.a)
Dada una lista de enteros con la siguiente definición:
TYPE
LInt = POINTER TO NodoLista;
NodoLista = RECORD
Info : INTEGER;
Sig : LInt;
END;
Este ejercicio consiste en la implementación de un procedimiento iterativo, el cual recibe
una lista de enteros LInt y elimina los valores negativos de esta.
(* Procedimiento encargado de eliminar los valores negativos de listaEnt *)
PROCEDURE NoNegativos(VAR listaEnt : LInt);
VAR lAux, lDelete : LInt;
BEGIN
IF (listaEnt <> NIL) THEN
(* Se utiliza un puntero auxiliar para recorrer la lista *)
lAux := listaEnt;
(* Se controla siempre contra el segundo elemento *)
WHILE (lAux <> NIL) AND (lAux^.Sig <> NIL) DO
IF (lAux^.Sig^.Info < 0) THEN
(* Se ajusta la estructura de la lista*)
lDelete := lAux^.Sig;
lAux^.Sig := lAux^.Sig^.Sig;
(* Se libera la memoria de la celda eliminada *)
DISPOSE(lDelete)
ELSE lAux := lAux^.Sig
(* Se avanza el puntero auxiliar a la siguiente celda *)
END;
END;
(* Caso inicial de que el primer elemento sea negativo *)
IF (listaEnt^.Info < 0) THEN
lDelete := listaEnt;
listaEnt := listaEnt^.Sig;
DISPOSE(lDelete)
END
END
END NoNegativos;
Página 1 de 5
Ejercicio 1.b)
Utilizando la definición de lista LInt se pide escribir una función iterativa, tal que dadas dos
listas ordenadas de enteros, la misma debe resolver la intersección de estas, dando como
resultado una lista ordenada.
(* Función que retorna la interesección de las listas l1 y l2 *)
(* Precondición: l1 y l2 están ordenadas y no tienen elementos repetidos *)
PROCEDURE Interseccion(l1 : LInt; l2 : LInt) : LInt;
(*
Punteros auxiliares: lRes contiene una referencia a la lista resultado y
lMov es usado para recorrer la lista resultado creando las celdas.
l1 y l2 son usados para recorrer las listas.
*)
VAR lRes, lMov : LInt;
BEGIN
lRes := NIL;
(* Si alguna de las dos listas es NIL entonces no hay más elementos de
intersección. *)
WHILE (l1 <> NIL) AND (l2 <> NIL) DO
IF (l1^.Info = l2^.Info) THEN
IF (lRes = NIL) THEN
(* Primer elemento de la lista resultado *)
NEW(lRes);
lRes^.Info := l1^.Info;
lRes^.Sig := NIL;
lMov := lRes
ELSE
NEW(lMov^.Sig);
lMov^.Sig^.Info := l1^.Info;
lMov^.Sig^.Sig := NIL
lMov := lMov^.Sig;
END;
l1 := l1^.Sig;
l2 := l2^.Sig
ELSIF (l1^.Info < l2^.Info) THEN
l1 := l1^.Sig
ELSE
l2 := l2^.Sig
END
END;
RETURN lRes
END Interseccion;
Página 2 de 5
Ejercicio 2.a)
Dada la siguiente definición extendida de árbol binario de búsqueda en modula 2:
TYPE
ABB = POINTER TO ABBNode;
ABBNode = RECORD
Dato : INTEGER;
CantSubIzq : CARDINAL;
Izq : ABB;
Der : ABB;
END;
La cual almacena en cada nodo la cantidad de hijos izquierdos + 1, se pide la implementación de
un procedimiento recursivo que inserte un elemento en dicho árbol manteniendo consistente la
estructura del mismo:
(*
Procedimiento que inserta el elemento k en el ABB t, manteniendo consistente la
información de la cantidad de hijos izquierdos.
Asumimos que el elemento a insertar no pertenece al árbol.
*)
PROCEDURE Insertar(VAR t : ABB; k : INTEGER);
BEGIN
(* Paso Base encargado de crear un nodo *)
IF (t = NIL) THEN
NEW(t);
t^.Dato := k;
t^.CantSubIzq := 1;
t^.Izq := NIL;
t^.Der := NIL
ELSE
IF (k < t^.Dato) THEN
(* Al desplazarme a la izquierda incremento la cantidad de hijos
izquierdos del nodo corriente *)
t^.CantSubIzq := t^.CantSubIzq + 1;
Insertar(t^.Izq, k)
ELSE
Insertar(t^.Der, k)
END
END
END Insertar;
Página 3 de 5
Ejercicio 2.b)
Usando la definición anterior de ABB, se pide la construcción de una función tal que dado un
árbol del tipo ABB y un natural k, retorne el k-ésimo elemento menor del árbol:
(*
Función que retorna el k ésimo elemento menor de t.
Asumimos que el árbol no tiene elementos repetidos.
*)
PROCEDURE KMenor(t : ABB; k : CARDINAL) : ABB;
(* Se utiliza el propio t para recorrer el árbol *)
BEGIN
IF (k = 0) THEN
RETURN NIL
ELSE WHILE (t <> NIL) AND (k <> t^.CantSubIzq) DO
IF (k < t^.CantSubIzq) THEN
t := t^.Izq
ELSE
k := k - t^.CantSubIzq;
t := t^.Der
END
END;
RETURN t
END
END KMenor;
Página 4 de 5
Ejercicio 3.
Dado un conjunto de primitivas sobre lista de naturales y lista de pares de naturales, se pide la
construcción de una función tal que dada una lista de naturales retorne una lista de pares de
naturales, correspondiente al producto cartesiano de los elementos de la lista de entrada. Para esto
se definen las siguientes rutinas recursivas auxiliares:
(* Función que retorna la concatenación en una nueva lista de l y l2. *)
PROCEDURE AppendLP(l : LParNat; l2 : LParNat): LParNat;
BEGIN
IF EmptyLP(l) THEN
RETURN l2
ELSIF EmptyLP(l2) THEN
RETURN l
ELSE
RETURN ConsLP(HeadLP(l),AppendLP(TailLP(l),l2))
END
END Concat;
(* Función que retorna una lista de pares, resultado de combinar el natural
x con todos los elementos de l. *)
PROCEDURE Combinar(x : CARDINAL; l : LNat): LParNat;
BEGIN
IF Empty(l) THEN
RETURN ConsLP(CrearPar(x,x),NullLP())
ELSE
RETURN ConsLP(CrearPar(x,Head(l)),
ConsLP(CrearPar(Head(l),x),
Combinar(x,Tail(l))))
END
END Combinar;
(* Función que retorna el producto cartesiano de los elementos de l *)
PROCEDURE ProdCart(l : LNat):LParNat;
BEGIN
IF Empty(l) THEN
RETURN NullLP()
ELSE
RETURN AppendLP(Combinar(Head(l),Tail(l)),ProdCart(Tail(l)))
END
END ProdCart;
In.Co. - Instituto de Computación
Página 5 de 5
Descargar