Instituto de Computación - Facultad de Ingeniería - Universidad de la República Examen de Programación 2 Febrero de 2005 Ejercicio 1. a) PROCEDURE AgregarElementos(lista : ListaEnt; VAR listacp : ListaCompEnt); VAR nuevocp, reccp: ListaCompEnt; valor, cont: INTEGER; BEGIN NEW(nuevocp); nuevocp^.sig := listacp; /* Creo celda dummy para simplificar el caso de borde */ listacp := nuevocp; reccp := nuevocp; WHILE (lista <> NIL) DO valor := lista^.info; cont := 1; WHILE ((lista^.sig <>NIL) AND (lista^.sig^.info = valor)) DO cont := cont + 1 lista := lista^.sig; END WHILE ((reccp^.sig <> NIL) AND (reccp^.sig^.info < valor)) DO reccp := reccp^.sig; END IF ((reccp^.sig = NIL) OR (reccp^.sig^.info > valor)) THEN NEW(nuevocp); nuevocp^.info := valor; nuevocp^.cant := cont; nuevocp^.sig := reccp^.sig; reccp^.sig := nuevocp; reccp := nuevocp; ELSE reccp^.sig^.cant := reccp^.sig^.cant + cont; reccp := reccp^.sig; END END reccp := listacp; listacp := listacp^.sig; DISPOSE(reccp); END AgregarElementos Instituto de Computación - Facultad de Ingeniería - Universidad de la República b) PROCEDURE EliminarOcurrencia(valor: INTEGER; VAR listacp : ListaCompEnt); VAR antcp, auxcp: ListaCompEnt; BEGIN antcp := NIL; auxcp := listacp; WHILE (( auxcp <> NIL) AND (auxcp^.info < valor)) DO antcp := auxcp; auxcp := auxcp^.sig; END IF ((auxcp <> NIL) AND (auxcp^.info == valor)) THEN IF (auxcp = listacp) THEN IF (auxcp^.cant = 1) THEN listacp := listacp^.sig; DISPOSE(auxcp); ELSE auxcp^.cant := auxcp^.cant -1; END ELSE IF (auxcp^.cant = 1) THEN antcp^.sig := auxcp^.sig; DISPOSE(auxcp); ELSE auxcp^.cant := auxcp^.cant -1; END END END END EliminarOcurrencia Instituto de Computación - Facultad de Ingeniería - Universidad de la República Ejercicio 2. a) PROCEDURE EliminarConUnHijo ( VAR a : AB ) ; VAR tmp : AB; BEGIN IF (a <> NIL) THEN IF ((a^.left = NIL) AND (a^.right <> NIL)) THEN tmp := a; a := a^.right; DISPOSE(tmp); EliminarConUnHijo(a); ELSIF ((a^.left <> NIL) AND (a^.right = NIL)) THEN tmp := a; a := a ^.left; DISPOSE (tmp); EliminarConUnHijo(a); ELSE EliminarConUnHijo(a^.left); EliminarConUnHijo(a^.right); END END END EliminarConUnHijo b) Para solucionar este problema existen varios enfoques posibles. Se presenta una solución en la cual una única función halla el máximo y a la vez calcula el nivel. Otra opción válida era realizar una función que encuentre el máximo elemento en el árbol y otra función que para un elemento dado halle el nivel en el cual se encuentra en el árbol. (* PRE: no vacío a *) PROCEDURE NivelDelMaximo ( a : AB ) : CARDINAL; VAR NivelMax : CARDINAL; BEGIN NivelMax := 1; EncontrarNivel(a, a^.info, NivelMax); RETURN NivelMax; END NivelDelMaximo PROCEDURE EncontrarNivel(a : CARDINAL); VAR max_l, max_r : INTEGER; niv_l, niv_r : CARDINAL; BEGIN IF (a<>NIL) THEN IF (a^.info > Max) THEN Max := a^.info; END max_l := Max; niv_l := NivActual +1; AB; VAR Max : INTEGER; VAR NivActual : Instituto de Computación - Facultad de Ingeniería - Universidad de la República EncontrarNivel(a^.left,max_l, niv_l); max_r := Max; niv_r := NivActual+1; EncontrarNivel(a.^right,max_r, niv_r); IF (max_l > max_r) THEN IF (max_l > Max) THEN Max := max_l; NivActual:= niv_l; END ELSIF (max_r > Max) THEN Max := max_r; NivActual:= niv_r; END END EncontrarNivel Instituto de Computación - Facultad de Ingeniería - Universidad de la República Ejercicio 3. Para resolver el ejercicio se utiliza el TAD Cola (de ARBOL), el mismo está definido por las siguientes operaciones: TYPE Queue; (* Procedimiento que crea una cola vacía *) PROCEDURE Create(VAR q : Queue); (* Procedimiento encargado de encolar el elemento t en la cola q *) PROCEDURE Enqueue(t : ARBOL; VAR q : Queue); (* Función que retorna TRUE sii la cola q es vacía *) PROCEDURE Empty(q : Queue):BOOLEAN; (* Función que elimina el primer elemento de la cola q.*) (* Pre: NOT Empty(q); *) PROCEDURE Dequeue(VAR q : Queue); (* Función que retorna el primer elemento de la cola q.*) (* Pre: NOT Empty(q); *) PROCEDURE Front(q : Queue): ARBOL; PROCEDURE ImprimirNivelesPares(t : ARBOL); VAR impar, par : Queue; actual : ARBOL; BEGIN IF (t <> NIL) THEN Create(impar); Create(par); Enqueue(t, impar); WHILE (NOT Empty(impar) AND NOT Empty(par)) DO WHILE (NOT Empty(impar)) DO actual := Front(impar); Dequeue(impar); actual := actual^.PrimerHijo; WHILE (actual <> NIL) DO Enqueue(actual, par); actual := actual^.SigHermano; END END WHILE (NOT Empty(par)) DO actual := Front(par); Dequeue(par); WriteCard(actual^.Dato); actual := actual^.PrimerHijo; WHILE (actual <> NIL) DO Enqueue(actual, impar); actual := actual^.SigHermano; Instituto de Computación - Facultad de Ingeniería - Universidad de la República END END END ImprimirNivelesPares;