taller 3aldeapocaterra.mypressonline.com/recursos/tip-mod3.pdf · 2010-01-14 · taller 3:...

27
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

Upload: others

Post on 29-May-2020

6 views

Category:

Documents


1 download

TRANSCRIPT

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.