1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
--| 13/03/2012 --| PROGRAMA PRINCIPAL --| Implementa un módulo genérico con el TAD pila, pero haciendo uso de una implementación dinámica. --| Utiliza el ejercicio anterior para probar el módulo sin modificar ni una línea. -- Librerias: with ada.text_io, ada.integer_text_io, pila_dinamica; use ada.text_io, ada.integer_text_io; -- Programa principal: procedure ada8x03 is -- Se define el tipo de datos que se quiere guardar en cada Nodo de la Pila, en este caso un registro: type datos is record num:natural; car:character; end record; -- Se instancia y emplea el paquete pila_dinamica: package pilaD is new pila_dinamica(datos); use pilaD; -- Variables: temp:datos; p:ptPila; eleccion:integer; -- Instrucciones del programa principal: begin -- Primer menu: put_line("Menu:"); put_line(" 1. Inicializar"); put_line(" 0. Salir"); get(eleccion); while eleccion not in 0..1 loop put( "Opcion no valida, pruebe de nuevo: " ); get(eleccion); end loop; -- Si se inicaliza la pila se accede al segundo menu: if eleccion = 1 then inicializar(p); put_line("Pila inicializada."); -- Segundo menu: new_line; new_line; put_line("Menu:"); put_line(" 1. Insertar"); put_line(" 2. Extraer"); put_line(" 3. Solo leer"); put_line(" 0. Salir"); while eleccion /= 0 loop get(eleccion); while eleccion not in 0..3 loop put( "Opcion no valida, pruebe de nuevo: " ); get(eleccion); end loop; case eleccion is -- Insertar: when 1 => put("Inserte un numero de DNI: "); get(temp.num); put("Insertar la letra del DNI: "); get(temp.car); insertar(p, temp); -- Extraer: when 2 => if esVacia(p) then put_line("La pila esta vacia."); else extraer(p, temp); put("El DNI extraido: "); put(temp.num); put(temp.car); new_line; end if; -- Leer: when 3 => if esVacia(p) then put_line("La pila esta vacia."); else temp := leer(p); put("El DNI leido: "); put(temp.num); put(temp.car); new_line; end if; -- Salir: when 0 => -- Antes de terminar la ejecucion del programa se elimina lo que quede de la Pila: borrar(p); when others => NULL; end case; new_line; new_line; if eleccion /= 0 then put("oK, qué más desea hacer: "); end if; end loop; end if; end ada8x03; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
--| 13/03/2012 --| ESPECIFICACIÓN/DECLARACIÓN DE LA PILA DINÁMICA --| PRECONDICIÓN: --| La función a la hora de ser incluida en el programa principal deberá de enviar el tipo de dato que se usara de forma genérica aquí para ser almacenado en los Nodos de la Pila. --| Una posible sentencia seria: "package pilaD is new pila_dinamica( datos ); use pilaD;" --| Se ha de tener en cuenta, con la ayuda de la funcion esVacia(), de comprobar si hay Nodos en la Pila antes de ponerse a leer o extraerlos. generic -- EL tipo de datos recibido desde la función privada es un tipo de datos privado. type datos is private; package pila_dinamica is -- Se define el tipo "ptPila" como privado, en la zona privada se definira. type ptPila is private; -- Se definen las cabeceras de las funciones contenidas en el fichero de implementacion: procedure inicializar( p:in out ptPila ); function esVacia( p:in ptPila ) return boolean; procedure insertar( p:in out ptPila; d:in datos ); function leer( p:in ptPila ) return datos; procedure extraer( p:in out ptPila; d:out datos ); procedure borrar( p:in out ptPila ); -- Desde la zona privada, se detalla como son las variables declaradas previamente como privadas: private type nodo; -- Se define la cabecera de tipo Nodo. type ptNodo is access nodo; -- Se crea un tipo "ptNodo" que apuntara al tipo Nodo. type pila; -- Se define la cabecera de tipo Pila. type ptPila is access pila; -- El tipo declarado con anterioridad como privado se le especifica que va a ser un puntero a "pila"s. -- Se termina de definir el tipo Nodo, elemento contendra el tipo de Datos que definimos en generic como privado, siguiente es un puntero a otro Nodo. type nodo is record elemento:datos; siguiente:ptNodo; end record; -- Se termina de definir el tipo Pila, que es un registro que guarda el número total de nodos que posee la Pila y el puntero al primer Nodo. type pila is record numNodos:integer; primero:ptNodo; end record; end pila_dinamica; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
--| 13/03/2012 --| IMPLEMENTACIÓN DE LA PILA DINÁMICA -- El siguiente paquete permite borrar la memoria dinámica. with unchecked_deallocation; -- Funciones del paquete: package body pila_dinamica is --| INICIALIZA UNA PILA: --| Precondición: Se ha de recibir un puntero que apunte a un tipo pila. --| Poscondición: El puntero ahora apunta a una pila recién creada y con sus valores reseteados a 0/null. procedure inicializar( p:in out ptPila ) is begin p := new pila; p.numNodos := 0; p.primero := null; end inicializar; --| INDICA SI UNA PILA ES VACÍA O NO: --| Precondición: Se ha de recibir un puntero que apunte a un tipo pila. --| Poscondición: Se devuelve true si no hay nodos en la pila o false en caso contrario. function esVacia( p:in ptPila ) return boolean is begin if p.numNodos > 0 then return false; else return true; end if; end esVacia; --| INSERTA DATOS EN UN NUEVO NODO EN LA PILA: --| Precondición: Se ha de recibir un puntero que apunte a un tipo pila. Y un tipo privado con datos a insertar en la Pila. --| Poscondición: Se crea un nuevo Nodo, se rellena y se inserta al comienzo de la Pila. procedure insertar( p:in out ptPila; d:in datos ) is temp:ptNodo; -- Puntero temporal begin temp := new nodo; -- Se hace que el enlace apunte a un nuevo Nodo. temp.elemento := d; -- Se copia la información en el elemento del nuevo Nodo. temp.siguiente := p.primero; -- El nuevo nodo apunta donde apuntaba "p.primero" (al que ahora va a ser el segundo nodo o a null) p.primero := temp; -- Pila ahora apunta al nuevo nodo. p.numNodos := p.numNodos + 1; -- Se aumenta el contador de Nodos en 1. end insertar; --| DEVUELVE LOS DATOS DEL PRIMER NODO DE LA PILA: --| Precondición: Se ha de recibir un puntero que apunte a un tipo pila. --| Poscondición: Se devuelven los datos del primer Nodo de la Pila. function leer( p:in ptPila ) return datos is begin return p.primero.elemento; end leer; --| DEVUELVE LOS DATOS DEL PRIMER NODO DE LA PILA, EL NODO ES BORRADO A CONTINUACIÓN: --| Precondición: Se ha de recibir un puntero que apunte a un tipo pila. Y un tipo privado con datos a insertar en la Pila. El contador de Nodos no debe ser inferior a 1. --| Poscondición: Se devuelve por referencia los datos del primer Nodo de la Pila y se elimina dicho Nodo. procedure extraer( p:in out ptPila; d:out datos ) is -- Procedimiento para liberar la memoria de un Nodo: procedure borrar is new unchecked_deallocation(nodo, ptNodo); temp:ptNodo; -- Puntero temporal begin d := p.primero.elemento; -- Se copian los datos del primer Nodo de la Pila en "d" (parametro de salida) temp := p.primero; -- Se hace que temp apunte al primer Nodo de la Pila. p.primero := p.primero.siguiente; -- Ahora se hace que el puntero de la Pila apunte al segundo Nodo en vez del priero que es donde apunta ahora. borrar(temp); -- Se borra el Nodo al cual apunta "temp", es decir, el primer Nodo de la Pila. p.numNodos := p.numNodos - 1; -- Por ultimo se disminuye en 1 el contador de Nodos. end extraer; --| BORRA TODOS LOS NODOS DE LA PILA: --| Precondición: Se ha de recibir un puntero que apunte a un tipo pila (el puntero no puede estar sin inicializar). --| Poscondición: Se borran todos los Nodos de la Pila. procedure borrar( p:in out ptPila ) is procedure borrar is new unchecked_deallocation(nodo, ptNodo); procedure borrar is new unchecked_deallocation(pila,ptPila); temp:ptNodo; begin while p.primero /= null loop temp := p.primero; p.primero := p.primero.siguiente; borrar(temp); end loop; borrar(p); end borrar; end pila_dinamica; |