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 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
--| 17/03/2012 --| Implementa un módulo genérico con el TAD bicola. Desarrolla también un programa de prueba de las operaciones. with ada.text_io, ada.integer_text_io, bicola_dinamica; use ada.text_io, ada.integer_text_io; procedure ada8x08 is -- Declaración del tipo de dato a guardar en los Nodos de la Bicola: type datos is record num:integer; end record; -- Instanciación del paquete de Bicolas: package bicolaD is new bicola_dinamica(datos); use bicolaD; -- Variables: eleccion:natural; b:ptBicola; temp:datos; --| SOLICITA UN NÚMERO NATURAL EN UN RANGO DADO PARA LOS MENUS: --| Precondición: Se reciben tres parámetros naturales, el primero de salida y los otros dos de entrada. --| Poscondición: Se solicita un numero natural(e) comprendido entre un rango(i..f), si el rango no es valido se repite la operación recursivamente. procedure getEleccion(e:out natural; i,f:in natural) is begin get(e); if e not in i..f then put(" Opción no valida, pruebe de nuevo: "); getEleccion(e,i,f); end if; end getEleccion; --| IMPRIME EL CONTENIDO DE LA LISTA JUNTO A SU POSICION: --| Precondición: Se ha de recibir un puntero a una bicola. --| Poscondición: Se imprime todo el contenido de la bicola. procedure imprimir(b:in ptBicola ) is temp:datos; begin put_line(" Contenido de la bicola: "); new_line; put(" Números: "); for pos in 1..cuantosDatos(b) loop temp := leerPosicion(b, pos); put(temp.num, width=>2); put(", "); end loop; new_line;new_line; end imprimir; begin -- Primer menú: put_line("Menú:"); put_line(" 1. Inicializar la bicola"); put_line(" 0. Salir"); getEleccion(eleccion, 0, 1); if eleccion = 1 then inicializar(b); put_line(" Bicola inicializada."); while eleccion /= 0 loop -- Segundo menú: new_line; new_line; put_line("Menú:"); put_line(" 1. Insertar Izquierda"); put_line(" 2. Insertar Derecha"); put_line(" 3. Extraer Izquierda"); put_line(" 4. Extraer Derecha"); put_line(" 5. Borrar Izquierda"); put_line(" 6. Borrar Derecha"); put_line(" 7. Imprimir Bicola"); put_line(" 8. Cuantos Datos hay"); put_line(" 0. Salir"); getEleccion(eleccion, 0, 8); -- Condicional de operaciones: case eleccion is -- Insertar izquierda: when 1 => put(" Número a insertar: "); get(temp.num); insertarIzq(b,temp); -- Insertar derecha: when 2 => put(" Número a insertar: "); get(temp.num); insertarDer(b,temp); -- Extraer izquierda: when 3 => if not hayDatos(b) then put_line(" La bicola esta vacía."); else extraerIzq(b,temp); put(" Dato extraido: "); put(temp.num,width=>2); end if; -- Extraer derecha: when 4 => if not hayDatos(b) then put_line(" La bicola esta vacía."); else extraerDer(b,temp); put(" Dato extraido: "); put(temp.num,width=>2); end if; -- Borrar izquierda: when 5 => if not hayDatos(b) then put_line(" La bicola esta vacía."); else borrarIzq(b); end if; -- Borrar derecha: when 6 => if not hayDatos(b) then put_line(" La bicola esta vacía."); else borrarDer(b); end if; -- Imprimir Bicola: when 7 => if not hayDatos(b) then put_line(" La bicola esta vacía."); else imprimir(b); end if; -- Cuantos datos hay: when 8 => put(" Hay "); put(cuantosDatos(b),width=>0); put_line(" datos."); -- Salir: when 0 => liberar(b); when others => null; end case; end loop; end if; end ada8x08; |
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 |
--| 17/03/2012 --| ESPECIFICACION DE LA BICOLA: --| PRECONDICION: --| Durante la instanciación del paquete se ha de enviar el tipo de dato a guardar en los Nodos de la Bicola. --| Se ha de controlar mediante hayDatos() de no extraer datos si no los hay. generic -- Se obtiene el tipo de datos en la instanciación de la librería y se especifica que es privado y limitado. type datos is private; package bicola_dinamica is -- Se define el tipo ptBicola como privado, se termina de declarar en la zona privada. Es necesario incluir el tipo aquí para poderlo usar en las cabeceras de las funciones. type ptBicola is private; -- Cabeceras de las funciones: procedure inicializar( b:in out ptBicola ); function hayDatos( b:in ptBicola ) return boolean; function cuantosDatos( b:in ptBicola ) return natural; procedure insertarIzq( b:in out ptBicola; d:in datos ); procedure insertarDer( b:in out ptBicola; d:in datos ); function leerPosicion( b:in ptBicola; p:in positive ) return datos; procedure extraerIzq( b:in out ptBicola; d:out datos ); procedure extraerDer( b:in out ptBicola; d:out datos ); procedure borrarIzq( b:in out ptBicola ); procedure borrarDer( b:in out ptBicola ); procedure liberar( b:in out ptBicola ); -- Zona privada: private -- Se definen el resto de tipos, tanto para los nodos como para la bicola: type nodo; type ptNodo is access nodo; type bicola; type ptBicola is access bicola; type nodo is record elemento :datos; anterior :ptNodo; siguiente:ptNodo; end record; type bicola is record nodos :natural; primero:ptNodo; ultimo :ptNodo; end record; end bicola_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 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
--| 17/03/2012 --| IMPLEMENTACION DE LA BICOLA: -- Paquete para liberar memoria dinámica. with unchecked_deallocation; package body bicola_dinamica is --| INICIALIZA LA COLA: --| Poscondición: Se ha de recibir un puntero de tipo ptBicola como entrada/salida. --| Precondición: Se hace que el puntero apunte a una nueva bicola y se inicializa todo a 0/null. procedure inicializar( b:in out ptBicola ) is begin b := new bicola; b.nodos := 0; b.primero := null; b.ultimo := null; end inicializar; --| INDICA SI HAY DATOS EN LA BICOLA: --| Poscondición: Se ha de recibir un puntero de tipo ptBicola como entrada/salida que apunta a una bicola. --| Precondición: Se devuelve un true si hay nodos en la bicola o un false en caso contrario. function hayDatos( b:in ptBicola ) return boolean is begin if b.nodos = 0 then return false; else return true; end if; end hayDatos; --| INDICA CUANTOS DATOS HAY EN LA BICOLA: --| Poscondición: Se ha de recibir un puntero de tipo ptBicola como entrada/salida que apunta a una bicola. --| Precondición: Devuelve el numero de datos/nodos que hay en la bicola. function cuantosDatos( b:in ptBicola ) return natural is begin return b.nodos; end cuantosDatos; --| INSERTA DATOS EN LA BICOLA POR LA IZQUIERDA: --| Poscondición: Se ha de recibir un puntero a una bicola como entrada/salida y los datos a guardar. --| Precondición: Inserta un nuevo Nodo al principio. procedure insertarIzq( b:in out ptBicola; d:in datos ) is temp:ptNodo := new nodo; begin temp.elemento := d; if b.nodos = 0 then temp.anterior := null; temp.siguiente := null; b.primero := temp; b.ultimo := temp; else temp.anterior := null; temp.siguiente := b.primero; b.primero.anterior := temp; b.primero := temp; end if; b.nodos := b.nodos + 1; end insertarIzq; --| INSERTA DATOS EN LA BICOLA POR LA DERECHA: --| Poscondición: Se ha de recibir un puntero a una bicola como entrada y salida, y el dato a guardar. --| Precondición: Se inserta un nuevo Nodo al final. procedure insertarDer( b:in out ptBicola; d:in datos ) is temp:ptNodo := new nodo; begin temp.elemento := d; if b.nodos = 0 then temp.anterior := null; temp.siguiente := null; b.primero := temp; b.ultimo := temp; else temp.siguiente := null; temp.anterior := b.ultimo; b.ultimo.siguiente := temp; b.ultimo := temp; end if; b.nodos := b.nodos + 1; end insertarDer; --| DEVUELVE LOS DATOS DE LA IZQUIERDA DE LA BICOLA: --| Poscondición: Se ha de recibir un puntero a una bicola como entrada, y un numero positivo indicando el Nodo a devolver. --| Precondición: Se devuelve el Nodo que indique la posición recibida. function leerPosicion( b:in ptBicola; p:in positive ) return datos is temp:ptNodo := b.primero; pos:positive := 1; begin while pos < p loop temp := temp.siguiente; pos := pos +1; end loop; return temp.elemento; end leerPosicion; --| EXTRAE DATOS DE LA BICOLA POR LA IZQUIERDA: --| Poscondición: Se ha de recibir un puntero a una bicola como entrada y salida, y un parámetro como salida para devolver los datos. --| Precondición: Se devuelve por referencia los datos del primer Nodo y después se elimina. procedure extraerIzq( b:in out ptBicola; d:out datos ) is procedure borrar is new unchecked_deallocation(nodo,ptNodo); aux:ptNodo; begin d := b.primero.elemento; aux := b.primero; if b.nodos = 1 then b.primero := null; b.ultimo := null; else b.primero := b.primero.siguiente; b.primero.anterior := null; end if; b.nodos := b.nodos - 1; borrar(aux); end extraerIzq; --| EXTRAE DATOS DE LA BICOLA POR LA DERECHA: --| Poscondición: Se ha de recibir un puntero a una bicola como entrada y salida, y un parámetro como salida para devolver los datos. --| Precondición: Se devuelve por referencia los datos del ultimo Nodo y después se elimina. procedure extraerDer( b:in out ptBicola; d:out datos ) is procedure borrar is new unchecked_deallocation(nodo,ptNodo); aux:ptNodo; begin d := b.ultimo.elemento; aux := b.ultimo; if b.nodos = 1 then b.primero := null; b.ultimo := null; else b.ultimo := b.ultimo.anterior; b.ultimo.siguiente := null; end if; b.nodos := b.nodos - 1; borrar(aux); end extraerDer; --| BORRA UN DATO DE LA BICOLA POR LA IZQUIERDA: --| Poscondición: Se ha de recibir un puntero a una bicola como entrada y salida. --| Precondición: Se elimina el primer Nodo de la Bicola. procedure borrarIzq( b:in out ptBicola ) is procedure borrar is new unchecked_deallocation(nodo,ptNodo); aux:ptNodo; begin aux := b.primero; -- Se copia el puntero hacia el Nodo 1 a borrar. if b.nodos = 1 then b.primero := null; -- Si solo hay un Nodo se resetean los punteros de la bicola. b.ultimo := null; else -- En caso contrario: b.primero := b.primero.siguiente; -- Se hace que el primero ahora sea el 2 Nodo. b.primero.anterior := null; -- Ahora, el primer nodo que antes era segundo, se hace que anterior sea null. end if; b.nodos := b.nodos - 1; borrar(aux); end borrarIzq; --| BORRA UN DATO DE LA BICOLA POR LA DERECHA: --| Poscondición: Se ha de recibir un puntero a una bicola como entrada y salida. --| Precondición: Se elimina el ultimo Nodo de la Bicola. procedure borrarDer( b:in out ptBicola ) is procedure borrar is new unchecked_deallocation(nodo,ptNodo); aux:ptNodo; begin aux := b.ultimo; if b.nodos = 1 then b.primero := null; b.ultimo := null; else b.ultimo := b.ultimo.anterior; b.ultimo.siguiente := null; end if; b.nodos := b.nodos - 1; borrar(aux); end borrarDer; --| BORRA TODOS LOS DATOS Y LA BICOLA: --| Poscondición: Se ha de recibir un puntero a una bicola como entrada y salida. --| Precondición: Se eliminan todos los Nodos y por ultimo la Bicola. procedure liberar( b:in out ptBicola ) is procedure borrar is new unchecked_deallocation(nodo, ptNodo); procedure borrar is new unchecked_deallocation(bicola, ptBicola); aux:ptNodo; begin if b.primero /= null then aux := b.primero; b.primero := b.primero.siguiente; liberar(b); borrar(aux); else borrar(b); end if; end liberar; end bicola_dinamica; |