Examen Mayo 2017
Pregunta 1
(Prueba escrita teoría, 0.5 puntos)Crear un árbol AVL dada la siguiente secuencia de números enteros: . Se deberán describir los pasos de cada inserción y cómo va quedando el árbol tras cada una de ellas
Pregunta 2
(Prueba escrita teórica, 0.5 punto)De las diferentes implementaciones de listas dinámicas estudiadas en clase, enumerar cuáles de ellas se ajustan a la relación operación->orden de complejidad para todas las operaciones que se presentan a continuación. Justifique su respuesta
construir
→O(1)
insertarFinal
→O(1)
eliminarPrincipo
→O(1)
pertenece
→O(n)
- Lista cabecera-final
- Lista circular con puntero final
- Lista circular estática
Pregunta 3
(Prueba escrita teoría, 1.5 punto)Considere el siguiente diagrama y estado de una implementación estática que simula el uso de memoria dinámica de un árbol binario de búsqueda para datos de tipo String
a)
b)
Belen | David | Jesús | Antonio | Soto | Alfonso | Almudena
7 2 | 0 0 | 1 5 | 0 0 | 0 0 | 2 0 | 0 4
cabLibres: 6
carArbolBB: 3
Pregunta 4
(Prueba escrita práctica, 1,5 puntos)Dado un árbol binario cuyos nodos son de tipoTElem
y éste se encuentra definido en la unidaduElem
de la siguiente forma:TElem=Integer
.
a)
Se pide implementar una operación que devuelva el valor de la suma máxima de las ramas del árbol. En el árbol del ejemplo la suma máxima es 44.
function sumaMax(a:TArbolB):integer;
var hi,hd:TArbolB;
maxi,maxd:integer;
begin
if not esArbolBVacio(a) then begin // Caso recursivo
// Llamada recursiva
hijoI(hi, a);
maxi := sumaMax(hi);
hijoD(hd, a);
maxd := sumaMax(hd);
// Retorno del valor maximo
if maxi > maxD then
sumaMax := raiz(a) + maxi
else
sumaMax := raiz(a) + maxd;
end
else // Case base
sumaMax := 0;
end;
b)
Codificar toda la unidaduRecorridos
que contenga los subprogramas necesarios para mostrar por pantalla los valores de todas las hojas de un árbol binario. Con el fin de evitar la violación de acceso y favorecer el encapsulamiento indique todas las operaciones y unidades necesarias para llevar a cabo este recorrido.
procedure preorden(a:TArbolB);
var e:TElemento;
aux:TArbolB;
begin
// -------------------------------------[ Añadir elemento a la lista, antes de los hijos izq y dch ]
getRaiz(a, e); printElemento(e); write(', ');
// -------------------------------------
// Recursividad del hijo Izq
hijoI(a, aux);
if not esArbolBVacio(aux) then preorden(aux);
// Recursividad del hijo Izq
hijoD(a, aux);
if not esArbolBVacio(aux) then preorden(aux);
end;
Pregunta 5
(Prueba escrita práctica, 4,5 puntos)Un empresario con diferentes negocios quiere embarcarse en uno nuevo: gimnasios low cost. Aunque este tipo de gimnasios lleva tiempo de moda, suelen utilizar instalaciones muy grandes, con muchas máquinas y salas disponibles para distintas actividades. Esto hace que no todos los barrios de una ciudad como Madrid tengan este tipo de gimnasios o los tengan cerca, por ello, el empresario ha decidido trasladar el concepto a todos los barrios que pueda, creando una red de gimnasios low cost de tamaño pequeño, los small&low-cost gyms. De esta forma, el tamaño de cada gimnasio vendrá dado por los locales disponibles que encuentre en cada barrio donde se vayan a instalar. No en todos los gimnasios se podrán realizar las mismas actividades (que dependerán del tamaño del gimnasio), aunque sí quiere asegurar que todos tengan un número razonable de máquinas para fitness.Los usuarios de la nueva marca de gimnasios, podrán acceder con la misma cuota de socios a cualquier gimnasio de la red, con independencia del barrio donde se encuentre, ya sea el distrito de su residencia, de su trabajo o cualquier otro.Cada gimnasio estará caracterizado por un nombre, su dirección y el distrito en el que se ubica, y la lista de actividades que se pueden practicar en él (Bodypump, Zumba, Burn, Yoga, Abs attack, etc). Los diferentes gimnasios del mismo distrito están conectados entre sí, y también con los de los diferentes distritos contiguos. Por ejemplo, observando el mapa de los 21 distritos de Madrid, los gimnasios del distrito 1 estarán conectados con todos los gimnasios de los distritos 3, 5, 7, 8, 14 y 20.Toda la información de los gimnasios abiertos por el empresario se encuentra almacenada en una base de datos. Para leer de la base de datos se proporciona para su uso (y no hay que implementar) el siguiente subprograma:PROCEDURE ReadGymFromDB(VAR nombre: String; VAR direccion: TDireccion; VAR distrito: String; VAR actividades: TActividades; VAR error: Boolean);
TDireccion = RECORD calle: String; numero: Integer; END
TActividades = RECORD actividades: ARRAY[1..10] OF String; numeroActividades: Integer; END;
El subprogramaReadGymFromDB
devuelve ennombre
el nombre del gimnasio, endireccion
la información de la calle y número donde se encuentra el gimnasio que está leyendo en ese momento, endistrito
el nombre del barrio donde se encuentra el gimnasio, enactividades
las diferentes actividades que oferta el gimnasio y, por último, la devolución de la variable booleanaerror
indicará cuándo se ha llegado al final de la consulta y no hay que seguir consultando información de gimnasios, por tanto devolveráFALSE
indicando que se ha leído correctamente la información de un gimnasio (y por tanto no hay error) oTRUE
cuando se haya llegado al final de la información y la lectura no contiene información útil. Se invocará al procedimientoReadGymFromDB
las veces que sean necesarias para ir cargando secuencialmente la información de los gimnasios desde la base de datos hasta que la variable error indique que no hay más información nueva que leer.
a)
Definir el tipo de datosTRedGimnasios
para representar la información en memoria principal de la red de gimnasios. Además de utilizar los tipos que se proporcionan, se deberán crear todos los tipos que se consideren necesarios para estructurar de forma adecuada la información. Cada tipo deberá estar en una unidad diferente.A continuación implementar un procedimiento (y su llamada en el programa principal) para cargar en memoria principal toda la información de la red de gimnasios almacenada en la base de datos. Si para ello se necesitan operaciones de los diferentes tipos de datos proporcionados, así como de los nuevos creados, deberán implementarse también en sus unidades correspondientes.Hay que tener en cuenta que para construir de forma adecuada la red, no sólo hay que utilizar el subprograma de consulta a la base de datos ReadGymFromBD para leer los datos de los diferente gimnasios, sino que también es necesario saber, una vez conocidos cuáles son todos los gimnasios de la red, qué distritos son contiguos y qué gimnasios tiene cada uno (para poder conectar unos gimnasios con otros). Esta información se puede obtener mediante el siguiente subprograma (se supone ya implementado):PROCEDURE ReadContiguousDistrictsFromDB(nombre_gym: String; VAR distritosContiguos: TDistritosContiguos);
Donde la variabledistritosContiguos
devolverá el listado de distritos adyacentes al del distrito donde se encuentra el gimnasio de nombre pasado como entrada a través de la variablenombre_gym
. El tipoTDistritosContiguos
se encuentra definido en la unidaduDistritosContiguos
como sigue:TDistritosContiguos = RECORD distritos: ARRAY[1..21] OF String; numDistritos: Integer END;
Y para consultar si un distrito está incluido en un listadoTDistritosContiguos
se dispone de la siguiente interfaz (no hay que implementarlo):FUNCTION ContieneDistrito(distritos: TDistritosContiguos; distrito: String): Boolean;
uses uElementoGym, uListaA;
type
TRedGimnasios = ^TNodoGrafo;
TNodoGrafo = record
info:TElementoGym;
aristas:TListaA;
sig:^TNodoGrafo;
end;
type
TElementoGym = record
nombre:string;
direccion:TDireccion;
distrito:string;
listaActividades:TActividades;
end;
var
nombre:string;
direccion:TDireccion;
distrito:string;
actividades:TActividades;
error:Boolean;
distritosContiguos: TDistritosContiguos
g:TGrafo;
begin
// Insertar nodos en el grafo junto con su lista de adyacencias
error := False
while not error do begin
ReadGymFromDB(nombre, direccion, distrito, actividades, error);
if not error then begin
// Insertar nodo
crearElemGym(auxe, nombre, direccion, distrito, actividades);
insertarNodo(g, auxe);
// Insertar adyacencias
ReadContiguousDistrictsFromDB(nombre, distritosContiguos);
setAdyacenciasRef(g, listaAdyacencias);
end;
end;
end.