Taller 3aldeapocaterra.mypressonline.com/recursos/TIP-MOD3.pdf · 2010-01-14 · Taller 3:...
Transcript of Taller 3aldeapocaterra.mypressonline.com/recursos/TIP-MOD3.pdf · 2010-01-14 · Taller 3:...
Fundación Misión Sucre
Colegio Universitario de Caracas
Taller 3: Estructuras de Datos Dinámicas
Objetivo
Diseñar y programar en lenguaje C soluciones utilizando estructuras de datos
dinámicas
Contenido
Presentación del taller………………………………………………………………. 62
Buenas Prácticas de Programación……………………………………………….. 64
Conceptos a revisar…………………………………………………………………. 64
Desarrollo del Taller…………………………………………………………………. 73
Ejercicios……………………………………………………………………… 73
62
Presentación del taller
En el taller anterior se realizaron actividades para reforzar los conocimientos
básicos que permiten crear un programa utilizando estructuras de datos estáticas.
Así, se realizaron ejercicios sobre punteros, arreglos, arreglos
multi-dimensionales, funciones de manejo de cadenas, arreglos de cadenas,
estructuras y sentencia typedef. En esta oportunidad, se abordarán las
estructuras de datos dinámicas para dar conclusión al contenido de la unidad
curricular ubicada dentro del Programa Nacional de Formación en Sistemas e
Informática.
Te recomendamos realizar algunos ejercicios propuestos para consolidar los
conocimientos adquiridos por estos talleres y poder definir tu preparación para
este ultimo taller de estructura de datos dinámico. En estos ejercicios propuestos
encontraras una autoevaluación que te permitirá conocer tu rendimiento en los
conceptos básicos de lenguaje C.
Estos ejercicios están presentes en los anexos de esta guía, muchos éxitos.
Esta tercera guía taller contempla manejar la programación con las estructuras
dinámicas básicas de: listas, pilas y colas. El propósito es guiar a los estudiantes a
la consolidación de los conocimientos adquiridos en clase.
Los ejercicios presentados en este material están divididos en tres fases de
desarrollo, que contemplan lo siguiente:
Fase 1: El alumno correrá extractos de programa “en frío” comentando
debidamente línea por línea y determinando la función que cumple este
extracto dentro de un programa fuente para trabajar con un tipo específico
63
de estructura dinámica.
Fase 2: El alumno deberá armar el archivo fuente básico para trabajar con
la estructura dinámica en discusión tomando los extractos trabajados en la
fase 1.
Fase 3: Se presentan varios ejercicios que permiten la instalación de un
laboratorio a desarrollar por los estudiantes.
Es indispensable que los conceptos involucrados en el tema se hayan trabajado
con los alumnos con anterioridad por el docente asesor, a su vez se recomienda
una revisión de estos conocimientos antes de iniciar el presente taller. Por otra
parte, dado que los ejercicios iniciales de entendimiento de código son necesarios
para la elaboración de laboratorios posteriores y debido a que las soluciones a
estos laboratorios pueden ser variadas en estilo de programador a programador
las soluciones a este taller deben ser estudiadas junto al profesor asesor el que
guiará y orientará el logro de las mismas.
Para facilitar el uso de la guía de ejercicios se incluye una breve descripción de la
simbología usada.
Simbología a usar:
Fase 1: ¿Que hace el programa?
Fase 2: Armar el código fuente
Fase 3: Desarrollar programa
64
Buenas Prácticas de Programación
En el taller 1 se enumeran las prácticas consideradas como de “buen
programador” haciendo referencia a características específicas del Lenguaje C, en
el taller 2 se hace énfasis en las mismas. En este taller el alumno debe respetar la
estructura de código establecida como un ejemplo de “buenas prácticas de
programación”.
Conceptos a revisar
Las estructuras básicas que se han estudiado hasta ahora tienen una limitación
importante: no pueden cambiar de tamaño durante la ejecución; es decir, los
arreglos están compuestos por un número fijo de elementos, el cual se determina
al inicio de la creación del programa. Está claro que se pueden construir “arreglos
dinámicos”, pero una vez creados, su tamaño será fijo y cualquier modificación en
el tamaño requiere de la reconstrucción del arreglo desde el principio.
Una de las aplicaciones de la memoria dinámica y los punteros son las estructuras
dinámicas de datos. Éstas nos permiten crear estructuras de datos adaptadas a
necesidades reales a ser cubiertas en un programa y permiten crear estructuras
de datos flexibles, ya sea en cuanto al orden, la estructura interna o las relaciones
entre los elementos que las componen.
Dependiendo del número de punteros y de las relaciones entre los nodos,
podemos distinguir varios tipos de estructuras dinámicas como son: listas abiertas,
pilas, colas, listas circulares o listas cerradas, listas doblemente enlazadas,
árboles simples, árboles binarios, árboles binarios de búsqueda , árboles AVL,
árboles B, tablas HASH, grafos, y diccionarios.
65
El presente taller, tiene como propósito que el estudiante consolide conocimientos
fundamentales en las estructuras de datos dinámicas básicas simples: listas
abiertas, pilas y colas. Para ello se debe tener en cuenta los siguientes conceptos:
Nodo: Las estructuras de datos están compuestas de otras pequeñas estructuras
que se denominan nodos o elementos y que agrupan los datos con los que
trabajará el programa y además uno o más punteros autoreferenciales, es decir,
punteros a objetos del mismo tipo nodo.
Una estructura básica de un nodo para crear listas abiertas, pilas o colas simples
de datos seria:
struct nodo
{
int dato;
struct nodo *otronodo;
};
El campo "otronodo" puede apuntar a un objeto del tipo nodo. De este modo, cada
nodo puede usarse para construir listas de datos, y cada uno mantendrá ciertas
relaciones con otros nodos.
Para acceder a un nodo de la estructura sólo se necesita un puntero a un nodo.
Gráficamente se puede representar al nodo anterior, de la siguiente forma:
Listas abiertas: cada elemento sólo dispone de un puntero, que apuntará al
siguiente elemento de la lista o valdrá NULL si es el último elemento.
Pilas: son un tipo especial de lista, conocidas como listas LIFO (Last In, First Out:
el último en entrar es el primero en salir). Los elementos se "amontonan" o apilan,
de modo que sólo el elemento que está encima de la pila puede ser leído, y sólo
pueden añadirse elementos encima de la pila.
66
Colas: otro tipo de listas, conocidas como listas FIFO (First In, First Out): El
primero en entrar es el primero en salir). Los elementos se almacenan en fila, pero
sólo pueden añadirse por un extremo y leerse por el otro.
Se realiza una breve revisión de los conceptos implícitos en cada una de las
estructuras de datos a estudiar.
LISTAS
Concepto:
Es la forma más simple de estructura de datos dinámica. Los nodos se organizan
de modo que cada uno apunta al siguiente, y el último no apunta a nada, es decir,
el puntero del nodo siguiente vale NULL.
Implementación:
Para representar en lenguaje C esta estructura de datos se utilizan los punteros ya
estudiados en el taller anterior. El nodo típico para construir listas tiene la siguiente
forma:
struct lista { int dato; struct lista *siguiente; };
67
Debe notarse que de ésta forma, cada elemento de la lista sólo contiene un dato
de tipo entero, pero en la práctica no hay límite en cuanto a la complejidad de los
datos a almacenar en la estructura.
Cuando se crea una lista debe estar vacía por lo que debe representarse con la
constante NULL, para crearla se hace lo siguiente:
struct lista *miLista;
miLista = NULL;
Es decir, cuando el puntero que usamos para acceder a la lista vale NULL,
diremos que la lista está vacía:
Normalmente se definen varios tipos que facilitan el manejo de las estructuras, en
C una declaración de tipos para las listas puede ser:
typedef struct _nodo { int dato; struct _nodo *siguiente; } tipoNodo; typedef tipoNodo *pNodo;
typedef tipoNodo *Lista;
tipoNodo es el tipo para declarar nodos, evidentemente.
pNodo es el tipo para declarar punteros a un nodo.
Lista es el tipo para declarar listas, note que cualquier puntero a un nodo es una lista,
cuyo primer elemento es el nodo apuntado.
Es muy importante que en el programa nunca se pierda el valor del puntero al
primer elemento, de lo contrario será imposible acceder al nodo y no se podrá
liberar el espacio de memoria que ocupa.
NULL Lista
68
Operaciones Básicas:
Las operaciones básicas con listas son:
• Añadir o insertar elementos. • Buscar o localizar elementos. • Borrar elementos. • Moverse a través de una lista, anterior, siguiente, primero.
Se debe tomar en cuenta que no es igual insertar un nodo en una lista vacía, o al
principio de una lista no vacía, o al final, o en una posición intermedia. Una
explicación de cada uno de estos procesos escapa de los objetivos de este taller,
se recomienda haber revisado estos conceptos previamente al mismo.
PILAS
Concepto:
Como mencionamos anteriormente una pila es un tipo especial de lista, Dado que
una pila es una lista abierta sigue siendo muy importante no perder el valor del
puntero al primer elemento, igual que pasa con las listas abiertas.
Un ejemplo para entender las pilas es una pila de periódicos. Sólo es posible
añadir periódicos en la parte superior de la pila, y sólo pueden tomarse del mismo
extremo, por ello se conocen conocidas como listas LIFO (del inglés Last In, First
Out) el último en entrar es el primero en salir.
Implementación:
El nodo para construir pilas es el mismo que vimos para la construcción de listas:
69
struct pilas { int dato; struct pilas *siguiente; };
La definición de tipos para pilas es muy similar a la que se realiza para manejar
listas, tan sólo cambian algunos nombres:
typedef struct _nodo
{
int dato;
struct _nodo *siguiente;
} tipoNodo;
typedef tipoNodo *pNodo;
typedef tipoNodo *Pila;
donde:
tipoNodo es el tipo para declarar nodos, evidentemente.
pNodo es el tipo para declarar punteros a un nodo.
Pila es el tipo para declarar pilas.
Operaciones básicas:
Las inserciones (push) y eliminaciones (pop) en una pila se hacen siempre en un
extremo, lo que se considera como el primer elemento de la lista es en realidad el
último elemento de la pila.
70
Las pilas tienen un conjunto de operaciones muy limitado, aparte de las
operaciones comunes a todos como son inicializar, y vacía (nos indica si la pila
está vacía) sólo permiten las operaciones de insertar "push" y eliminar "pop":
• Push: Añadir un elemento al final de la pila.
• Pop: Leer y eliminar un elemento del final de la pila.
• Tope: Retorna el elemento en el tope de la pila.
COLAS
Concepto:
Una cola es un tipo especial de lista abierta en la que sólo se puede insertar nodos
en uno de los extremos de la lista y sólo se pueden eliminar nodos en el otro
extremo.
Este tipo de lista es conocido como lista FIFO (por el inglés First In First Out), el
primero en entrar es el primero en salir.
El símil cotidiano es una cola para comprar, por ejemplo, la cola para las entradas
al circo. Los nuevos compradores de entradas sólo pueden colocarse al final de la
cola, y sólo el primero de la cola puede comprar la entrada.
71
Implementación:
El nodo típico para construir pilas es el mismo que vimos en los capítulos
anteriores para la construcción de listas y pilas:
struct colas { int dato; struct colas *siguiente;
};
Los tipos que se definen para manejar colas son similares a los que utilizamos
para manejar listas y pilas, tan sólo cambian algunos nombres:
typedef struct _nodo { int dato; struct _nodo *siguiente; } tipoNodo; typedef tipoNodo *pNodo; typedef tipoNodo *Cola;
donde:
tipoNodo es el tipo para declarar nodos.
pNodo es el tipo para declarar punteros a un nodo.
Cola es el tipo para declarar colas.
Dado que una que una cola es un tipo de lista abierta, nuevamente es muy
importante que no se pierda el valor del puntero al primer elemento, al igual que
pasa con las listas abiertas. Por otra parte, debido al funcionamiento de las colas,
también se debe mantener un puntero para el último elemento de la cola, que será
el punto donde se inserten nuevos nodos.
72
Operaciones básicas:
Además, como sucede con las pilas, las escrituras de datos siempre son
inserciones de nodos, y las lecturas siempre eliminan el nodo leído.
De nuevo nos encontramos ante una estructura con muy pocas operaciones
disponibles. Las colas sólo permiten añadir y leer elementos:
• Encolar: Inserta un elemento al final de la cola.
• Desencolar: Lee y elimina un elemento del principio de la cola.
• Frente: devuelve el elemento a la cabeza de la cola, pero no lo extrae.
Teniendo en cuenta que las lecturas y escrituras en una cola se hacen siempre en
extremos distintos, lo más fácil es insertar nodos por el final, a continuación del
nodo que no tiene nodo siguiente, y leerlos desde el principio. Se debe recordar
que leer un nodo implica eliminarlo de la cola.
73
Desarrollo del taller
Ejercicios
A continuación se presentan los ejercicios para el desarrollo del taller de
Estructuras Dinámicas, los ejercicios están agrupados por el tipo de estructura.
Recuerda revisar la simbología en la presentación del taller.
Ejercicios sobre LISTAS:
Ejercicio 1: ¿Acorde a listas, qué hacen los siguientes fragmentos de
código?. Recuerda incluir comentarios línea por línea.
/* */
void nueva(List_Array *list_ptr)
{
int k;
list_ptr->cant = 0; /* */
for(k = 0; k < LISTMAX; k++)
strcpy(list_ptr->list[k],"\0"); /* */
}
74
#define LISTMAX 10 /* */
typedef int Tipo_Elemento;
typedef struct
{
int cant; /* Para manejar la Cantidad de elementos en la Lista */
Tipo_Elemento list[LISTMAX];
} List_Array;
/* */
int insertar(List_Array *list_ptr, Tipo_Elemento *elemento)
{
if(list_ptr->cant == LISTMAX)
return (-1); /* */
else {
strcpy(list_ptr->list[list_ptr->cant], elemento);
list_ptr->cant++; /* */
return (1); /* */
}
}
/* */
75
int borrar(List_Array *list_ptr, int pos) {
int k;
/* */
if (pos < 0 || pos > list_ptr->cant-1)
return (-1); /* */
else {
/* */
for (k = pos; k < list_ptr->cant - 1; k++)
strcpy(list_ptr->list[k],list_ptr->list[k+1]);
list_ptr->cant--;
return (1); /* */
}
}
/* */
int buscar(List_Array *list_ptr, Tipo_Elemento *elemento) {
int k = 0;
while (k <= (list_ptr->cant - 1))
if (!strcmp(list_ptr->list[k], elemento)) /* */
return (k+1);
else
k++;
return (-1); /* */
}
/* */
int vacia(List_Array *list_ptr) {
76
if (list_ptr->cant == 0)
return (1); /* */
else
return (0); /* */
}
/* */
int numElementos(List_Array *list_ptr) {
return list_ptr->cant;
}
Ejercicio 2: Realiza un fragmento de código que encuentre y devuelva un
elemento sucesor dada una posición en la lista.
Ejercicio 3: Realiza un fragmento de código que encuentre y devuelva un
elemento predecesor dada una posición en la lista.
Ejercicio 4: Realiza dos fragmento de código: uno que devuelva el primer
elemento de la lista y el otro que devuelva el último elemento de la lista.
Ejercicio 5: Toma todos los fragmentos de código de los primeros
cuatro ejercicios y construye el código fuente para que lo puedas usar como base
en los ejercicios siguientes (si tienes dudas sobre como compilar un archivo en c
77
junto a otro donde colocas el código fuente revisa el anexo “ Línea de comandos
GCC”).
Ejercicio 6: Realiza un código para inserción en listas según el siguiente
algoritmo para inserción con ordenamiento ascendente.
1. Crear un nodo para el dato que vamos a insertar.
2. Si Lista es NULL, o el valor del primer elemento de la lista es mayor que el del
nuevo, se insertará el nuevo nodo en la primera posición de la lista.
3. En caso contrario, se buscará el lugar adecuado para la inserción, se tiene un
puntero "anterior". Se inicializa con el valor de Lista, y se avanza mientras anterior-
>siguiente no sea NULL y el dato que contiene anterior->siguiente sea menor o
igual que el dato que se quiere insertar.
Ahora ya se tiene anterior señalando al nodo adecuado, así que se inserta el nuevo
nodo a continuación de él.
Ejercicio 7: Realiza un código para borrar elementos de una lista según el
siguiente algoritmo: Recuerda que para eliminar un nodo se necesita disponer de
un puntero al nodo anterior.
1. Localizar el nodo a eliminar, si es que existe. (Pero sin perder el puntero al nodo
anterior, partir del nodo primero, y del valor NULL para anterior y avanzar
mientras nodo no sea NULL o mientras que el valor almacenado en nodo sea
menor que el que buscamos).
2. Nota que pueden darse tres casos:
1. Que el nodo sea NULL, esto indica que todos los valores almacenados en
la lista son menores que el que se busca y el nodo que se busca no existe.
Se retorna sin borrar nada.
78
2. Que el valor almacenado en nodo sea mayor que el que se busca, en ese
caso también se retorna sin borrar nada, ya que esto indica que el nodo
que se busca no existe.
3. Que el valor almacenado en el nodo sea igual al que se busca.
3. De nuevo existen dos casos:
1. Que anterior sea NULL. Esto indicaría que el nodo que se quiere borrar es
el primero, así que se modifica el valor de Lista para que apunte al nodo
siguiente al que se quiere borrar.
2. Que anterior no sea NULL, el nodo no es el primero, así que se asigna a
anterior->siguiente la dirección de nodo->siguiente.
4. Después de 7 u 8, se libera la memoria de nodo.
Laboratorios de Listas Propuestos
Nota: Para el desarrollo de los siguientes ejercicios de laboratorio se debe utilizar el
archivo fuente que contenga todas las funciones básicas para el manejo de las
estructuras, ej: “listas.h”, y se debe producir un archivo donde se desarrollará el programa
principal “.c” con las posibles variables a utilizar llamado, ej: "listas.c”.
Ejercicio 8: Realiza un programa que simule una lista de invitados a una
boda que permita a los novios insertar, buscar y eliminar un invitado de la lista.
Ejercicio 9: Agrega una función al ejercicio anterior que permita visualizar
en pantalla los invitados en lista.
Ejercicio 10: Realizar un programa que permita el ingreso de una lista de
números (enteros positivos) al usuario, indique la cantidad de elementos en la lista
y calcule el número mayor ingresado. El usuario indicará el final de su ingreso
ingresando -1. Para ello se pide que se escriba una función a utilizar llamada
Encontrar_Maximo() que retorne el máximo valor de la lista, y su posición. Se
79
debe dar el resultado en reporte en pantalla.
Ejercicio 11: Realiza una función que permita imprimir en pantalla los
números ingresados por el usuario ordenados en forma descendente.
Ejercicio 12: Realizar un programa que simule un diccionario, permita el
ingreso de palabras en el mismo, las ordene ascendentemente y que al final
imprima todos los elementos de la lista de palabras ingresadas en orden
alfabético.
Ejercicio 13: Realizar un programa que permita al usuario hacer una lista
de artículos a comprar en el supermercado, el programa debe permitir verificar si
la lista de mercado esta vacía, así como vaciar e imprimir la lista.
Ejercicios sobre PILAS:
Ejercicio 1: ¿Acorde a los conceptos de pilas, qué hacen los siguientes
fragmentos de código?. Recuerda incluir comentarios línea por línea.
#define MAXPILA 10 /* */
/* */
void nuevaPila(Tipo_pila *st_ptr)
{
st_ptr->cima = 0; /* */
80
}
/* */
int vacia(Tipo_pila *st_ptr)
{
if(st_ptr == NULL)
return 1; /* */
if(st_ptr->cima == 0)
return 1; /* */
else
return 0; /* */
}
/* */
Ejercicio 2: Realiza un fragmento de código que encuentre y devuelva el
elemento del tope de la pila.
Ejercicio 3: Realiza un fragmento de código que cree el tipo de estructura
para manejar las pilas.
Ejercicio 4: Realiza un fragmento de código que permita indicar si la una
pila esta llena.
81
Ejercicio 5: Realiza un código para la función pop en pilas según el
siguiente algoritmo
Algoritmo de la función "pop":
1. Hacer que nodo apunte al primer elemento de la pila, es decir a Pila.
2. Asignar a Pila la dirección del segundo nodo de la pila:
Pila->siguiente.
3. Guardar el contenido del nodo para devolverlo como retorno,
recuerda que la operación pop equivale a leer y borrar.
4. Liberar la memoria asignada al primer nodo, (del que se quiere
eliminar)
Ejercicio 6: Realiza un código para la función push en pilas según el
siguiente algoritmo:
Algoritmo de la función "push":
1. Crear un nodo para el valor que colocaremos en la pila.
2. Hacer que nodo->siguiente apunte a Pila.
3. Hacer que Pila apunte a nodo.
Ejercicio 7: Toma todos los fragmentos de código de los primeros
ejercicios y construye el código fuente para que lo puedas usar como base en los
ejercicios siguientes (si tienes dudas sobre como compilar un archivo en c junto a
otro donde colocas el código fuente revisa el anexo “ Línea de comandos GCC”).
82
Ejercicio 8: Realizar un programa que permita al usuario hacer un
programa que simule un estacionamiento para autos de una sola calle y un sólo
sentido (es decir, en forma de pila), deberá de manejar placas, poner límite
máximo de autos a estacionar, y poner una función para sacar auto, llamar al
programa autos.c, recuerda incluir las funciones en autos.h.
Ejercicio 9: Realizar un programa que complemente el programa anterior
agregando funciones push y pop para manejar la pila de autos, una función para
insertar los elementos en forma ordenada y otra función para imprimir los
elementos en reversa, llamar al programa autos_orden.c .
Ejercicio 10: Realizar un programa que permita al usuario crear una
pila que contenga la información de una la empresa “Motores C. A.”, encargada de
vender motores de vehículos. Por cada motor se tienen los siguientes datos:
serial, cilindros y caballos de fuerza. El ingreso de datos finalizará cuando el
usuario teclee al serial el valor -1. Este valor no debe ser parte de la pila. El
programa debe mostrar por pantalla los elementos o valores que se encuentran en
la pila.
Para el desarrollo de este laboratorio se debes usar el archivo que creaste en
ejercicio anterior que contiene todas las funciones básicas para el manejo de las
pilas “pila.h” y además se debe desarrollar un archivo que contenga la función
main con las posibles variables a utilizar llamado "pila.c”.
Ejercicio 11: Realizar un programa que permita al usuario crear una pila
que contenga información sobre las ventas efectuadas durante un día en la
litografía “ Mi Litografía C. A.”, se desea calcular el costo de cada palabra impresa,
83
sabiendo que cada letra tiene un costo de 3 BF. si es impresa con tinta negra y 5
BF. si es impresa a color. Se debe indicar a cada cliente el monto a pagar por el
trabajo a realizar (dependiendo si la cadena usa sólo tinta negra o a color)
sumándole el IVA calculado al 9%. El ingreso de datos finalizará cuando se
introduzca una cadena contenida con *** (3 asteriscos). Este registro, no debe ser
parte de la pila.
El programa debe mostrar por pantalla:
• El monto a pagar por cada cliente.
• Total en BF. de palabras impresas con tinta negra.
• Total en BF. de palabras impresas con tinta a color.
Para esto harán uso de una función llamada MostrarPila() la cual será desarrollada
por los estudiantes en la librería “pila.h”.
Ejercicio 12: Usando los conocimientos obtenidos sobre estructuras
dinámicas listas y pilas, escriba un programa que permita al usuario seleccionar
entre las siguientes opciones:
a) ingresar datos numéricos en una pila A,
b) ingresar datos numéricos en una pila B,
c) generar una lista ordenada con los números contenidos en
ambas estructuras y que la muestre por pantalla (las pilas
deberán quedar vacías)
d) finalizar el programa,
Mientras el usuario no elija la opción d), le será posible seguir seleccionando y
ejecutando opciones.
84
Ejercicios sobre COLAS:
Ejercicio 1: Realizar todas las funciones necesarias para el uso
adecuado de las colas, debe ser guardadas en un archivo llamado cola.h.
Defina las operaciones de: primero, último, encolar, desencolar,
numeroElementosEnCola, vaciar, eliminarElementoEnPosicion, posicion.
Ejercicio 2: Usando los conocimientos obtenidos sobre colas realice un
programa que permita crear una cola de personas ingresando su nombre, el
usuario debe indicar cuando desea dejar de ingresar más personas en la cola
tecleando ‘$’, luego debe presentar al usuario opciones que le permitan:
Conocer el último elemento de la cola, indicar el número de personas en la cola,
ingresar un nuevo elemento a la cola y eliminar elementos de la cola, el programa
debe indicar si la cola está vacía.
Ejercicio 3: Especificar las siguientes operaciones para el tipo abstracto
colas y diseñar los métodos que implementen las nuevas operaciones usando la
representación dinámica de las colas.
• Una operación que produzca la inversa de una cola.
• Una operación que concatene dos colas, es decir, que coloque los elementos de
una al final de la otra.
Muestra al usuario los elementos de la cola 1 y de la cola dos, y luego se debe
concatenar ambas colas y presentar los elementos de la cola concatenada en
pantalla indicando el primer elemento y el último.
85
Ejercicio 4: Diseñar dos algoritmos uno usando pilas y otro usando colas,
que decidan si una frase ingresada como una sucesión de caracteres leídos del
periférico de entrada es o no palíndrome. Recuerda que una frase se llama
palíndrome si la sucesión de caracteres obtenida al recorrerla de izquierda a
derecha (ignorando los blancos) es la misma que si el recorrido se hace de
derecha a izquierda, por ejemplo en la frase “dábale arroz a la zorra el abad”.
Ejercicio 5: Una cola medieval se comporta como una cola ordinaria, con
la única diferencia que los elementos almacenados en ella se dividen en dos
estamentos: nobles y plebeyos. Dentro de cada estamento, los elementos deben
ser atendidos en orden de llegada; pero siempre que haya nobles en la cola, éstos
deben ser atendidos antes que los plebeyos. Realiza un programa en C que
permita:
Especificar un tipo abstracto de datos para las colas medievales que disponga de
operaciones para:
– crear una cola medieval vacía,
– añadir un elemento nuevo a una cola,
– consultar el primer elemento de una cola,
– quitar el primer elemento de una cola,
– consultar el número de nobles en una cola,
– consultar el número de plebeyos en una cola,
– consultar si una cola es vacía o no.
Ejercicio 6: Se desea implementar una estructura de datos que permita
gestionar las tareas que se ejecutan en una CPU multitarea. Dentro del conjunto
de tareas se pueden diferenciar cinco niveles de prioridad, de 1 a 5, siendo el nivel
más prioritario el 1. Cuando hay tareas de nivel 1 éstas serán las primeras en
ejecutarse, si no hay de este nivel se ejecutarán las de nivel 2 y así sucesivamente
hasta que no haya tareas. El orden de ejecución dentro de un mismo nivel de
86
prioridad es por orden de llegada. Realizar un programa que simule la selección
de tareas de la CPU, seleccione las estructuras a utilizar acorde al planteamiento.
Ejercicio 7: Un concesionario de autos tiene un número limitado de
modelos, todos en un número limitado de colores distintos. Cuando un cliente
quiere comprar un automóvil, lo solicita de un modelo y color determinados. Si el
auto de ese modelo y color no está disponible en el concesionario, se toman los
datos del cliente (nombre), y se almacenan para ser atendida su petición cuando
el esté disponible. Si hay más de una petición con las mismas características, se
atienden las peticiones por orden cronológico.
a) Definir la estructura de datos más adecuada capaz de contener las peticiones
de un modelo y color de auto.
c) Definir una operación que, dado un cliente (nombre) que desea comprar un auto
de un modelo y color determinado, coloque sus datos como última petición de
ese modelo y color.
d)Elimine clientes a los que se les entregue el auto de un color y modelo dado.
Ejercicio 8: Una librería registra las peticiones de cualquier libro que no
tiene en ese momento. La información de cada libro consiste en el título del libro,
el precio (en BF), el número de libros en stock, y las peticiones del libro en estricto
orden de llegada. Cada petición consiste en el nombre de una persona y su C.I.
Implementa una operación que dado un cliente que pide un libro, vea si hay en
stock, y si quedan, actualice el stock con la venta de ese libro, y si no, guarde los
datos del cliente como última petición de ese libro.
87
Ejercicio 9: Un restaurante dispone de n número de mesas. De cada
mesa se sabe su código de identificación. Hay una cola de espera para ir
ocupando las mesas, de forma que, para cada elemento, se sabe el nombre de la
persona que ha hecho la reserva y el número de comensales que no debe exceder
de 5. Definir una operación que, dado un identificador de mesa libre, devuelve el
nombre de la persona que se encuentra de primera de la lista de clientes que
hayan hecho una reserva indicándole que puede pasar al comedor. La estructura
debe quedar convenientemente actualizada una vez la persona pase al comedor
saliendo así de la lista de espera. No se permiten reservas que excedan el número
de comensales por mesa. Realiza el programa para representar la reservación de
mesas del restaurante.
Ejercicio 10: En una tienda hay sólo 1 caja registradora, en la cual se
colocan los clientes con sus carros de la compra en orden de llegada. De la caja
registradora se guarda el número identificador de la caja, la recaudación
acumulada y los carros en espera. Por otro lado, en cada carro se amontonan los
distintos productos, de modo que tan sólo puede añadirse o extraerse el situado
en la parte superior. Por cada producto guardamos su nombre y precio.
- Definir la estructura más adecuada para guardar un carro de la compra y
explicar ¿por qué?
- Definir la estructura más adecuada para guardar una caja registradora explicar
¿por qué?
- Escribir una función denominada atender_cliente que dado un carro de la
compra, pase los productos que contiene por caja y calcule el costo a pagar.
- Desarrollar una función que calcule la recaudación de la caja después de pasar
los primeros n carros por cada una de ellas. n será un argumento de entrada que
no puede ser mayor que el número de carros en espera en la caja
Utilizar la estructura de datos más adecuada para devolver el resultado pedido en
cada uno de los casos.