Está en la página 1de 35
Segunda Edicién Libro de problemas. Fundamentos de programaci6n | Algoritmos, Estructuras de datos y vietos | Estructuras dindmicas fineales de datos (pilas, colas y listas enlazadas) 441 Las estructuras dindmicas de datos se pueden dividir en dos grandes grupos: pilas lineales colas. listas enlazadas arboles no lineales grafos Las estructuras dindmicas de datos se utilizan para almacenamiento de datos del mundo real que estén cambiando constantemente. Un ejemplo tipico ya lo hemos visto como estructura estatica de da- tos; la Jista de pasajeros de una linea aérea. Sj esta lista se mantuviera en orden alfabético en un array, serfa necesario hacer espacio para insertar un nuevo pasajero por orden alfabético. Esto requiere uti- lizar un bucle para copiar los datos de! registro de cada pasajero en el siguiente elemento del array. Si en su lugar se utilizara una estructura dindmica de datos, los nueves datos del pasajero se pueden in- sertar simplemente entre dos registros existentes sin un minimo esfuerzo. Las estructuras dindmicas de datos son extremadamente flexibles. Como se ha descrito anterior- mente, es relativamente fécil afiadir nueva informacién creando un nuevo nodo e inserténdolo entre nodos existentes. Se verd que es también relativamente facil modificar estructuras dindmicas de datos, eliminando o borrando un node existente. En este capitulo examinaremos Jas tres estructuras dindmicas lineales de datos: listas, colas y pi- las, dejando para el préximo capftulo las estructuras no lineales de datos: Arboles y grafos. Una estructura estdtica de datos es aquella cuya estructura se especifica en el momento en que se escribe el programa y no puede ser modificada por el programa. Los valores de sus diferen- tes elementos pueden variar, pero no su estructura, ya que ésta es fija. Una estructura dindmica de datos puede modificar su estructura mediante el programa. Puede ampliar o limitar su tamafio mientras se ejecuta el programa. 42.2. LISTAS Una lista lineal es un conjunto de elementos de un tipo dado que pueden variar en ntimero y donde cada elemento tiene un inico predecesor y un tinico sucesor o siguiente, excepto el primero y ultimo de la lista. Esta es una definicién muy general que incluye los ficheros y vectores. Los elementos de una lista lineal se almacenan normaimente contiguos —un elemento detras de otro— en posiciones consecutivas de la memoria. Las sucesivas entradas en una guia o directorio te- lefénico, por ejemplo, estén en lineas sucesivas, excepto en las partes superior e inferior de cada co- lumna, Una lista lineal se almacena en la memoria principal de una computadora en posiciones suce- sivas de memoria; cuando se almacenan en cinta magnética, los elementos sucesivos se presentan en sucesin en la cinta. Esta asignaci6n de memoria se denomina almnacenamiento secuencial. Posterior- mente se vera que existe otro tipo de almacenamiento denominado encadenade o enlazado. Las lineas asi definidas se denominan contiguas. Las operaciones que se pueden realizar con lis- tas lineales contiguas son: Insertar, eliminar o localizar un elemento. Determinar el tamafio —nuimero de elementos— de la lista. Recorrer la lista para localizar un determinado elemento. Clasificar los elementos de la lista en orden ascendente o descendente. Unir dos o mas listas en una sola. Ae who at 442 = Fundementos de programacién jet 6. Dividir una lista en varias sublistas. 7. Copiar la lista. 8. Borrar la lista. Una lista lineal contigua se almacena en la memoria de la computadora en posiciones sucesivas o adyacentes y sé procesa como un array unidimensional. En este caso, el acceso a cualquier elemento de la iista y la adicién de nuevos elementos es facil, sin embargo, la insercién o borrado requiere un desplazamiento de lugar de los elementos que fe siguen y, en consecuencia, el disefio de un algoritmo especifico. Para permitir operaciones con listas como arrays se deben dimensionar éstos con tamaiio suficiente para que contengan todos los posibles elementos de la lista. : Ejemplo 12.1 Se desea leer el elemento j-ésimo de una lista P. El algoritmo requiere conocer el mimero de elementos de la lista (su longitud, L). Los pasos a dar son: 1. Conocer longitud de la lista L. 2. SiL = 0 visualizar «error lista vacia». Si_no comprobar si el elemento j-ésimo esta dentro del rango permitido de elementos 1 <= j <= L; en este caso, asignar el valor del elemento P(j} a una variable B; si el elemento J-€simo no estd dentro del rango, visualizar un mensaje de error «elemento solicitado no exis- te en la lista». 3. Fin. aly | Ei pseudocddigo correspondiente seria: ' WW | procedimiento acceso(E lista: P; $ elementolista: B; ’ E entero: L, J} inicio ei L = 0 entonces escribir('Lista vacia’) si_no si (j >= 1) y (j <= L) entonces B < PLj] si_no escribir('ERROR: elemento no existente’) fin_si fin_si fin Ejemplo 12.2 toh 2st Borrar un elemento j de la lista P. Variables L longitud de fa lista J posicion del elemento a borrar I subindice del array P P lista Estructuras dindmicas lineales de datos (pilas, colas y jistas enlazadas) 443 Las operaciones necesarias son: 1, Comprebar si 1a lista es vacia. 2. Comprobar si el valor de J est4 en el rango del subindice I de la lista 1 <= J <= L. 3. Encaso de J correcto, mover los elementos j+1, j+2, ...,alas posiciones j, j+1, ..., respectivamente, con lo que se habrd borrado el antiguo elemento j. 4. Decrementar en uno el valor de la variable L, ya que la lista contendré ahora L — 1 elementos. EI algoritmo correspondiente sera: inicio ei L = 0 entonces escribir('lista vacia') si_no 2: Bei gal) leer (J) si (J >= 1) y (J <= L} entonces 7 desde I + J hasta L-1 hacer P[I] < P[I+1] fin_desde Le L-1 si_no escribir('Elemento no existe’) fin_si fin_si . fin listas Una lista contigua es aquella en que los elementos son adyacentes en la memoria o soporte di- reccionable. Tiene unos limites izquierdo y derecho o inferior/superior que ne pueden ser reba- jados cuando se le afiade un elemento. La insercidén o eliminacién de un elemento, excepto en fa cabecera o final de Ja lista, nece- sila una traslacién de una parte de los elementos de la misma: la que precede o sigue a la posi- cién del elemento madificado. Las operaciones directas de afiadir y eliminar se efectian énicamente en los extremos de la lista. Esta limitacién es una de las razones por las que esta estructura es poco utilizada. Sus gnemenets, emt ape oe Las Nstas enlazadas o de almacenamiento enlazado o encadenado son mucho més flexibles y po- tentes, y su uso es mucho mds amplio que las listas contiguas. 12.3. LISTAS ENLAZADAS' Los inconvenientes de las listas contiguas se eliminan con las listas enlazadas. Se. pueden almacenar los elementos de una lista lineal en posiciones de memoria que no sean contiguas o adyacentes. Una lista enlazada 0 encadenada es un conjunto de elementos en los que cada elemento contiene ja posicién —o direcci6n— del siguiente elemento de la lista. Cada elemento de la lista enlazada debe ' Las listas enlazadas se conocen también en Latinoamérica con el términe «ligadas» y «encadenadas». El término en in- glés es linked list, 444 Fundamenios de programacion tener al menos dos campos: un campo que tiene el valor del elemento y un campo (enlace, dink) que contiene la posicién del siguiente elemento, es decir, su conexi6n, enlace o encadenamiento. Los ele- mentos de una lista son enlazados por medio de los campos enlaces. Las listas enlazadas tienen una terminologia propia que se suele utilizar normalmente. Primero, los valores se almacenan en un nodo (Figura 12.1). Dato Enlace (valor elemento) o————— Figura 12.1. Nodo con dos campos. fie rite ‘Potmd bs A Una lista enlazada se muestra en la Figura 12.2. on ie 5S) 4)1] 7 | 18/19) 9 |) 7 | 45] + Ah Go fa ide no {5 ata [18] {19 {9 45] as b Figura 12.2. (a) array representado por una lista; (b) lista enlazada representada por una lista de enteros. Los componentes de un nodo se llaman campos. Un. nodo tiene al menos un campo dato o valor y un enlace (indicador 0 puntero) con el siguiente nodo. El campo enlace apunta (proporciona la di- reccién o teferencia de) al siguiente nodo de Ia lista. El ultimo nodo de la lista enlazada, por conve- nio, se suele representar por un enlace con 1a palabra reservada nil (nulo), una barra inclinada (/) y, en ocasiones, el simbolo eléctrico de tierra 0 masa (Figura 12.3). yA 4 | nil 4 | rad co Ghbendene Figura 12.3. Representacién del ultimo nodo de una lista. d La implementacién de una lista enlazada depende del lenguaje. C, C++, Pascal, PL/T, Ada y Mo- dula-2 utilizan como enlace una variable puntero, 0 puntero (apuntador) simplemente. Java no dis- pone de punteros, por consiguiente, resuelve el problema de forma diferente y almacena en el enlace la referencia al siguiente objeto nodo. Los lenguajes como FORTRAN y COBOL no disponen de este tipo de datos y se debe simular con una variable entera que actiia como indicador o cursor. En nues- Estructuras dinamicas lineales de datos {pilas, colas y listas enlazadas) 445 tro libro utilizaremos a partir de ahora el término puntero (apuntador) para describir el enlace entre dos elementos o nodos de una lista enlazada. Un puntero (apuntador) és una variable cuyo valor es la direccién o posicién de otra variable. En las listas enlazadas no es necesario que fos elementos de a lista sean almacenados en posicio- nes fisicas adyacentes, ya que el puntero indica dénde se encuentra el siguiente elemento de la lista, tal como se indica en la Figura 12.4. INFO SIG PRIMERO INFO SIG ti S16 v at O Shiesu SIG run Figura 12.4. Elementos no adyacentes de una lista enlazada. wig Por consiguiente, la insercién y borrade no exigen desplazamiento como en el caso de las listas contiguas. Para eliminar el 45." elemento (' INES ') de una lista lineal con 2.500 elementos [Figura §2.5 (a)] s6lo es necesario cambiar el puntero en el elemento anterior, 44.°, y que apunte ahora al elemento 46.7 (Figura 12.5 (b)]. Para insertar un nuevo elemento (* HIGINIO' } después del 43.° elemento, es ne- cesario cambiar el puntero del elemento 43.° y hacer que ¢l nuevo elemento apunte al elemento 44.° [Figura 12.5 (c}}. 5 GONZALO| HORACIO INES IVAN JUAN ZAYA HIGINIO | GONZALO| 6] HORACIO ol IVAN o|| JUAN eLL! ZAYA = |NULO ; () Figura 12.5. Insercién y borrado de elementos. 446 Fundamentos de programacién Una lista enlazada sin ningiin elemento se Hama fista vacfa. Su puntero inicial o de cabecera tie- ne el valor nulo (nil). - Una lista enlazada se define por: * El tipo de sus elementos: campo de informaci6n (datos) y campo enlace (puntero). * Un puntero de cabecera que permite acceder al primer elemento de la lista. ¢ Un medio para detectar el dltimo elemento de la lista: puntero nulo (nil). Ejemplo 12.3 El director de un hotel desea registrar el nombre de cada cliente a medida de su llegada al hotel, junto con el ndmero de habitacion que ocupa —el antiguo libro de entradas—. Tambien desea dis- poner en cualquier momento de una lista de sus clientes por orden alfabétice. Ya que no es posible registrar los clientes alfabética y cronolégicamente en la misma lista, se ne- cesita o bien listas alfabéticas independientes o bien afiadir punteros a la lista existente, con lo que s6lo se utilizar4 una tinica lista. El método manual en el Jibro requerfa muchos cruces y reescrituras; sin embargo, una computadora mediante un algoritmo adecuado lo realizara facilmente. Por cada nodo de la lista el campo de informacién o dates tiene dos partes: nombre del cliente y numero de habitacién. Si x es un puntero a uno de estos nodos, /fv}.nombre y Ifx} habitacion repre- sentaran las dos partes del campo informacidn. El listado alfabético se consigue siguiendo el orden de los punteros de la lista (campo puntero). Se utiliza una variable CABECERA (S) para apuntar al primer cliente. CABECERA © 3 ind Asi, CABECERA (S$) es 3, ya que el primer cliente, Antolin, ocupa el lugar 3. A su vez, el pun- tero asociado al nodo ocupade por Antolin contiene el valor 10, que es el segundo nombre de los clientes en orden alfabético y éste tiene como campo puntero el valor 7, y asi sucesivamente. El cam- po puntero del ultimo cliente, Tomas, contiene el puntero nulo indicado por un 0 ¢ bien una 2. Puntero 2 (finaly Habitacion 324 28 Nombre Registro S(=3) Tomas Cazorla Pérez Lépez. Sanchez Bautista Garcia Jiménez Apolinar Ws) Martin 205 Luzérraga Figura 12.6. Lista enlazada ce clientes de un hotel. Estructuras dindmicas fineales de datos (pilas, colas y listas enlazadas) 447. 12.4. PROCESAMIENTO DE LISTAS ENLAZADAS nOioneRiZA Para procesar una lista enlazada se necesitan las siguientes informaciones: mop a « Primer nodo (cabecera de la lista). “nby sbhndisest> + El tipo de sus elementos. . . 4 iq} ievysced Las operaciones que normalmente se ejecutan con listas incluyen: rah adinanienil 1. Recuperar informacién de un nodo especifico (acceso a un elemento). 2. Encontrar el node que contiene una informacién especifica (localizar la posicién de un ele- mento dado). 3. Insertar un nuevo nodo en un lugar especifico de la lista. wy 4. Insertar un nuevo nodo en relacién a una informacién particular. . 5. Borrar (eliminar) un nodo existente que contiene informacién especifica, wv 12.4.1. Implementacién de listas enlazadas con punteros Como ya hemos visto la representacién grafica de un puntero consiste en una flecha que sale del pun- tero y llega a la variable dindmica apuntada. [++ : Tua ab soites siden . . Para declarar una variable de tipo puntero: aol ue aut tipo puntero_a podra ser simple o estructurado. Operaciones con punteros: ~ Inicializacién fe kivr.s p © nulo A nolo para indicar que no apunta a ninguna variable. oqis “Epes Comparacién p = q Con los operadores = 0 <>. tga? Pp | +— al eb ndbiaser> pew , . q : 448 Fundamentos de programacién Asignacién pe < q_ Implica hacer que el puntero p apunte a donde apuntaba q. ves goed : as Creacién de variables dinaémicas ns Reservar (p) Reservar espacio en memoria para la variable dindmica. stage end Eliminacién de variables dindmicas } Liberar (p) Liberar el espacio en memoria ocupado por la variable dindmica. 5 af Bote “Variables dindmicas teseo tt b Variable simple o estructura de datos sin nombre y creada en tiempo de ejecucién. | ++_] Pp p> Para acceder a una variable dindmica apuntada, como no tiene nombre p > Las variables p — podran intervenir en toda operacién o expresién de las permitidas para una va- riable estdtica de su mismo tipo. Wary ne Nodo “au cwisiosh ssf Las estructuras dinémicas de datos estén formadas por nodos. Un nodo es una variable dinémica constituida por al menos dos campos: * el campo dato o valor (elemento); * el campo enlace, en este caso de tipo puntero (sig). Bet los A LIL Ly ico elemento sig [1 tipo registre: nodo /felemento es el campo que contiene la informacion : elemento //punt apunta al siguiente elemento de la estructura punt : sig {segun la estructura de que se trate podrd haber uno o varios campos de tipo punt} fin_registro “4 Creacién de Ja lista La creacién de la lista conlleva la inicializacién a nulo del puntero (inic), que apunta al primer ele- mento de la lista. Estructuras dinamicas fineales de datos (pilas, tipo puntero_a nodo: punt tipo_elements registro: fin_registro registro: nodo tipo_elemento elemento punt sig fin_registro var punt inic, posic, anterior tipo_elemento : elemento logice + encontrado inicio inicializar(inic) fin procedimiento inicializar(§ punt: inic) inicio inic — aulo fin _procedimiento inic Li4 LE nulo insercidn de un elemento La insercién tiene dos casos particulares: + Tnsertar el nuevo nodo en el frente, principio de la lista. * Insertar el nuevo nodo en cualquier otro lugar de la lista. colas y listas enlazades) 449 ~ tein tbesorg El procedimiento insertar inserta un nuevo elemento a continuacién de anterior, si ante- rior fuera nul significa que ha de insertarse al comienzo de la lista. insertar (inicio, anterior, elemento) 1° anterior > elemento =e a nulo inic avisast anterior | seit ab nbissriimiva AA pot sabe L8bO. 450 = Fundamentos de programacidn auxi — ogi? elemento sig | df 2° | T — auxi : 3° , . yyy i] auxi = v9 BY jazz] aneersor anterior > piad elemento 4 4° nulo ia OK i ait . tbevotg auxL at inic Lyvyy| i] +t auxi elemento sig MaPir uiged ob 1.° Situacidn de partida. 2° reservar (auxi). 3° Introducir la nueva informacién en auxi— elemento. >) nbinsent 4° Hacer que auxi— sig apunte a donde lo haciaanterior> sig. |. , 5° Conseguir que anterior->.sig apunte a donde lo hace auxi, eH noloroaH Bd procedimiento insertar{E/S punt: inic,anterior; \ansant * E tipo_elemento: elemento) ashisenk « var punt: auxi : . inicio Shinthsse1q Fa reservar (auxi) ‘i BISUT TOLT auxic.elemento © elemento ei anterior = nulo entonces auxi 3.sig ¢ inic inie © auxi ehora “| si_no , auxi-.sig © anterior-3.sig ; anterior>.sig <— auxi fin_si anterioy © auxi // Opcional fin_procedimiento Eliminacién de un elemento de una lista enlazada Antes de proceder a la eliminacién de un elemento de la lista, deberemos comprobar que no est4 va- cia. Para lo que podremos recurtir a la funci6n vacia. Estructuras dindmicas lineales de datos (pilas, cofas y listas enlazadas) 451 légico funeién vacia(E punt: inic} AA pine inicio devolver(inic = nulo) fin _funcidén Al suprimir un elemento de una lista consideraremos dos casos particulares: ake te ¢ El elemento a suprimir esta al principio de la lista. gio ; * El elemento se encuentra cualquier otro lugar de Ia lista. t . . RR Suprimir(inic, anterior, posic) hacer 1° se anterior why at insmigiqnni ei anterior + elemento agsien 1! h nginooer | eat990 5187 inic anterior ht t | _— &.S8T oiqmaia “Un sb oluslbS anterior -> sig elemento inic 452 Fundamentos de programacién 1° Situacién de partida feo. 2° anterior —.sig apuntaa donde posic —7.sig. at 3° liberar{posic). i procedimiento suprimir(E/S punt: inic, anterior, posic) inicio aque EA ei anterior = nulo entonces inic © posic>.sig A si_no oad « anterior >.sig © posic>.sig fin ai : Lior liberar (posic) anterior ¢ nulo // Opcicnal posic ¢ inic // Opcional fin_procedimiento Java y C# permiten la creacién de listas enlazadas vinculando objetos nodo sin el empleo de pun- teros, en el enlace se almacena la referencia al siguiente nodo de la lista. En estos lenguajes, aunque la implementacién de una lista enlazada resulta similar, hay que tener en cuenta que al crear un obje- to nodo se reserva espacio en memoria para é1 y que este espacio se libera automAéticamente, a través de un proceso denominado recoleccién automatica de basura, cuando dicho objeto (nado) deja de es- tar referenciado. 3 Recorrido de una lista enlazada | Para recorrer la lista utilizaremos una variable de tipo puntero auxiliar, procedimiento recorrer{E punt:inic]) war punt: posic inicio posic < inic mientras posic <> nulo hacer proc_escribir (posic3.elemento) posic € posic73,sig fin mientras fin_procedimiento Ejemplo 12.4 Calculo del namero de elementos de una lista enlazada. procedimiento contar(E punt: primero; S entero: n) war punt: p inicio neo //contader de elementos p ¢ primero mientras p <> nulo hacer nenei posic © posic >.sig fin_mientras fin_procedimiento Estructuras dindmicas lineales de datos (pitas, coias y fistas enlazadas) 453 Acceso a unr elernento de una lista enlazada. La biisqueda de una informacidén en una lista siraplemente enlazada sélo puede hacerse mediante un proceso secuencial 0 recorrido de la lista elemento a elemento, hasta encontrar la informacién busca- da o detectar el final de la lista. procedimiento consultar(E punt: inic; §$ punt: posic,anteriocr; E tipo_elemento: elemento; 8 légico: encontrado) inicio anterior + nulo posic © inic mientras no igual {posico.elemento,elemento) y (posic <> nulo) hacer { iquai es una funcién que compara les elementos que le pasamos como pardmetros, recurrimos a ella porque, si se tratara de registros, comparariamos Unicamente la informacién almacenada en un determinado campo } £2 anterior ¢ posic ~~ posic — posico.sig fin_mientras si igual (posic3.elemento, elemento) entonces encontrado « verdad ¥ si_no oatail ae] encontrado <— falso ‘ fin_si sonra fin procedimiento : vol Ejemplo 12.5 Encontrar el nodo de una lista que contiene la informacién de valor t, suponiendo que !a lista al- macena datos de tipo entero, procedimiento encontrar(E punt: primero E entero: t} : . var punt : p 1 entero: n 4 inicio 5 8 neo ' p primero ! mientras (p-.info <> t) y¥ (p <> nulo) hacer nenetl posic ¢ posic>.sig = fin_mientras —- ec si po.info = t entonces escribir('Se encuentra en el nodo ',n,'de la lista'} gsi_no ' escribir(‘Ne encontrado') fin_si ae) fin_procedimientec Considere que la informacién se encuentra alimacenada en la lista de forma ordenada, orden cre- ciente, y mejore la eficacia del algoritmo anterior. i 454 = Fundamentos de programacion procedimiento encontrar(E punt: primero E entero: t}) ae nus cesook var punt : p . entero: no Cote eet ' inicio a neo av fy uae o eb p © primero mientras (p —.info < t! y (p <> nule) hacer nenel posic «< posico.sig fin mientras on si p -.info = t entonces Gg escribir('Se encuentra en el nodo ',n,’ de la lista’). sy si_no my escribir(‘No encontrado’) fin_si fin_procedimiento cine imibesorg 12.4.2. Implementacién de listas entazadas con arrays fe fans thya deve Las listas enlazadas deberén implementarse de forma dindmica, pero si el lenguaje no lo permite, lo realizaremos a través de arrays, con lo cual impondremos limitaciones en cuanto al mimero de ele- mentos que podr4 contener la lista y estableceremos una ocupacién en memoria constante. Los nodos podran almacenarse en arrays paralelos 0 arrays de regisiros. ss001q_ ei: Cuando se empleen arrays de registros, el valor (dato o informacién) del nodo se almacenard en un campo y el enlace con el siguiente elemento se almacenara en otro. Otra posible implementacién, como ya se ha dicho antes, es con dos arrays: uno para los datos y otro para el enlace, . Un valor de puntero 0, o bien 2, indica el final de la lista. ab oben Ia wwitsoond + ogit sb eotob onaaom ELEMENTO SIG ELEMENTO SIG XOOGOOO000GOOL 1 2 1] 20000AK 000K XXKKXAAKARKKK 2) 4 2 | XXKKKXKXXKAKK 3 3 XMMKXAKXXKKKK 4) 6 4 | KXKKXXKKXKXXK 5 5 XXXKXKAKKAKKK 6; 0 6 | 2200000000004 Para definir la lista se debe especificar la variable que apunta al primer nodo (cabecera), que en nuestro caso denominaremos inic. inie «1 ix Para insertar un nuevo elemento, que siga a m( i] y sea seguide por m[2], lo dnico que se hard es modificar los punteros. Estruciuras dindmicas lineales de datos (pilas, colas y listas enlazadas) 455 M VD] XXX AAK 2 | KOKKXAXXKKO | 4 | B ] KOCK KAXAKX | OOD AKK | s | 5 | | Ca ectrecneety ed | o | } Como el nuevo elemento se coloca en la primera posicion libre deberemos tener un puntero vacio que apunte a dicha primera posicién libre. Es decir, utilizaremos el array para almacenar dos listas, la lista de elementos y la lista de vacios. Es, pues, necesario, al comenzar a trabajar, crear la lista de vacios de la forma que a continuacién se expone: * Vacio apunta al primer registro libre. venennwos oes + Enel campo sig de cada registro se almacena informacién sobre el siguiente registro disponible. + Cuando Heguemos al ultimo registro libre, su campo sig recibird el valor 0, para indicar que ya no quedan mds registros disponibles. ELEMENTO SIG - jo-chomicn- 1 2 2 3 “ . 3 vacio ¢— 1 3 4 : inic + 4 4 5 1h 26 5 6 Inv Insertar el primer elemento a “8 © Rib vacio ¢ 2 areres inie e 1 ae oni oft Al implementar una lista a través de arrays necesitaremos los procedimientos: ost A inicializar(t...} imiciar(...) consultar{...) insertar(...) suprimir(...) reservar(...} liberar(...) 15 y las funciones vacia(...} liena(...) ob 456 Fundamentos de programacién E! procedimiento reservar (...} nos proporcionaré la primera posicién vacia para almacenar un nuevo elemento y la efiminara de la lista de vacios, pasando el puntero de vacios (vacio) a la po- sicién siguiente, vacio toma el valor del siguiente vacio de la lista. Liberar(...) inserta un nuevo elemento en la lista de vacios. Se podrian adoptar otras solu- ciones, pero nuestro procedimiento liberar insertard el nuevo elemento en La lista de vacios por delaa- te, sobrescribiendo el campo m[posic] .sig para que apunte al que antes era el primer vacio. El puntero de inicio de los vacios (vacio) lo cambiara al nuevo elemento. Creacion de Ia lista Consideraremos el array como si fuera la memoria del ordenador y guardaremos en él dos listas: la lista de elementos y la de vacios. E! primer elemente de la lista de elementos esta apuntado por inic y, por vacio, el primero de la lista de vacios: const wes tem ne eal max = teun a EDBV ® tipo ; aigad + registro: tipo_elementco ye oreo A bs ernie, fin_registro registro: tipo_nodo tipo_elemento : elemento entero : sig { actia como puntero, almacenando ta posicién donde se encuentra el siguiente elemente de una lista } fin_registro array[1..Max]) de tipo_nodo: arr Pal Dame para bes as var entero 3 inic, posic, anterior, vacio arr 7m //m representa la memoria de nuestro ordenador tipo_elemento : elemento logico : encontrado inicic iniciar(m, vacio} inicializar(inic) fin Al comenzar: vetasenel gue LA. procedimiento inicializar(8 entero: inic) /flista de elementos inicio yet inic — 0 wet aah + fin_procedimiento “ eee a Estructuras dindmicas lineales de datos (pilas, colas y listas enlazadas) 457 elemento sig vacio « 1 indica que el primer registro libre es m[1] 1 inic + 0 inic sefala que no hay elementos en fa lista naa kw A O;m)/ nm), a) aol nw procedimiento iniciar(S arr: m; $ entero: vacio) //lista de vacios var entero: i inicio vacio — 1 desde i «© 1 hasta Max-1 hacer m[i].sig © i+] fin_desde mfMax].sig «+ 0 //Como ya no hay mAs posiciones libres a las que apuntar, recibe un 0 fin_procedimiento I 8 sed Ox Al trabajar de esta manera conseguiremos que la insercién 0 borrado de un determinado elemen- f to, n-ésimo, de Ia lista no requiera el desplazamiento de otros. Cal . ' fnsercién de un elemento Al actualizar una lista se pueden presentar dos casos particulares: 1 ¢ Desbordamiento (overflow). ¢ Subdesbordamiento o desbordamiento negativo (underflow). El desbordamiento se produce cuando la lista est Hena y la lista de espacio disponible esta vacia. El subdesbordamiento se produce cuando se tiene una lista vacia y se desea borrar un elemento de la misma. Luego, para poder insertar un nuevo elemento en una lista enlazada, es necesario comprobar que se dispone de espacio libre para ello. Al insertar un nuevo elemento en la lista deberemos recurrir al procedimiento reservar (...) que nos proporcionard, a través de auxi, la primera posicién vacia para almacenar en ella el nuevo elemento, eliminando dicha posicién de la lista de vacios. Por ejemplo, al insertar el primer elemento: elemento sig XXXKXXAXAXARK auxi« 1 vacio <— 2 458 Fundamentos de programacién : = ; ar . tar * vacio sefiala que la primera posicion libre es lal auxi < 1 “ * El campo sig del registro m[vacio] proporciona la siguiente posicién vacia y reservar haré que vacio apunite a esta nueva posicién vacio < 2 Al insertar un segundo elemento: . . . "O. * como vacio tiene el valor 2 auxi ¢ 2 ° * vacio € m[2].sig, es decir vacio © 3 nk Baal elemento sig T | 22000000000 a des 2 | OCU OXXKHKK auxi © 2 3 vacio — 3 procedimiento reservar{S entero: auxi; E arr: m; E/S entero: vacio) inicio gi vacio = 0 entonces ai} // Memoria agotada auxl + 0 : ATA si_no AOEWAS- OF auxi © vacio vacio © mi[vacio].sig fin_si fin_procedimiento addi] gf issilegiog LA ou 8b ndineent El procedimiento insertar colocara un nuevo elemento a continuacién de anterior, si anterior fue- ra 0 significa que ha de insertarse al comienzo de la lista. sintedow procedimiento insertar(E/S entero: inic, anterior; E tipso_elemento: elemento; i senicalil 6 E/S arr: m ; E/S entero: vacio) put var 7 entero: auxi inicio reservar (auxi.m, vacio} - . ‘ - is ,olqutsts 10d m[auxi].elemento «< elemento gi anterior = 0 entonces , mlauxi].sig < inic inic © auxi gi_no mf{auxi].sig «+ mlanterior].sig mfanterior].sig ¢- auxi fin si anterior ©— auxi // Opcional { Prepara anterior para que, si no especificamos otra cosa, la siguiente insercién se realice a continuacién de la actual} fin_procedimlento g & as Estructuras dindmicas lineales de datos (pilas, colas y listas enlazadas) 459 Consideremos la siguiente situacién y analicemos e] comportamiento que en ella tendrian los pro- cedimientos reservar ¢ insertar: Se desea insertar un nuevo elemente en la lista a continua- cién dei primero y la situacidn actual, tras sucesivas inserciones y eliminaciones, es como se muestra a continuacion: 1 | XXOKKAXKKKKAX | 2 2 | OOOKKXAKKAKK | 4 vacio — 3 3 5 . inic 1 4 | 90000000000 | «6 el sefialade 5 0 ia hista se B | XXXXXMXXXXXXX | O El nuevo elemento se colocard en el array en la primera posicidn libre y lo dnico que se hard es modificar los punteros. pie. it}m reservar ( } proporciona la primera posici6n libre > sinwibeat XR HHA RAK (ib Ta XXKAAK KARAM up fe omog auxi ¢ 3 nuevo_elemento * ofal KAKA KKKK KK vacio & 5 mn oH & WS Be MAKKKAKKARKKA m(3].elemento < nuevo_elemento como queremos insertar el nuevo elemento a continuacién dei primero de la lista, su anterior serd el apuntado por inic 2a anterior — 1 m(3].sig <— 2 mll].sig — 3 Eliminacién de un elemento we Para eliminar un elemento de Ja lista deberemos recurrir al procedimiento suprimir{...}, que,a su vez, llamara al procedimiento liberar{...} para que inserte el elemento eliminado en la lista de vacios. Supongamos que se trata de eliminar el elemento marcado con **##++444+44* cuya posicién es 3 olota: posic ¢+ 3 ta el elemento anterior af 3 ocupa en el array la posicién 2 te anterior <— 2 460 Fundamentos de programacion y el primer vacio esta en 5. Siendo el aspecto actual de la lista el siguiente: 9X elementa sig ve AOD By inic «= 1 T | OOOO XKXKKK anterior © 2 2 | 2000000000004 posic + 3 3 4 | 20000000000000 vacio & 5 5 6 we Al suprimir el elemento 3 la lista quedaria: . uA ‘ a “SUA ax. m(2].sig ¢— 4 ; ad woltibom mediante el procedimiento Liberar(...) incluimos el nueve vacio en la lista de vacios m(3)-sig ¢ 5 vacio & 3 como el que se suprime no es el primer elemento de Ia lista, el valor de inic no varia ‘ inic +1 elemento sig 1] 22000000000 2 | xxxxD0GC00KGK Bee encnaeeeees 4 | XXXAKXAKAXNKX g- oi procedimiento liberar(E entero: posic; E/S arr: m; E/3 entero: vacio} iniclo m[posic].sig © vacio 290 ndtosnints vacio © posic , lo ne wsnimils sist fin_procedimiento . le 2 . : jis piemall sey ue procedimiento suprimir(E/S entero: inic, anterior, posic; E/S arr: m; E/S entero: vacio) inicio si anterior = 0 entonces “=> Sigzoq inic © m[posic].sig si_no mfanterior]).sig <— m[posic].sig . fin_si iB Estructuras dinamicas lineales de datos (pilas, colas y listas enlazadas) 461 liberar(posic, m, vacio} anterior ¢— 0 // Opcional posic ¢ inic // Opcional { Las dos iltimas instrucciones preparan los punteros para que, sino se especifica otra cosa, la préxima eliminacidén se realice por el principio de la lista } fin_procedimiento Recorrido de una lista . El recorrido de la lista se realizaré siguiendo los punteros a partir de su primer elemento, el sefialado por inic. El procedimiento recorrer (. ..} que se implementa a continuacisn, al recorrer la lista va mos- trando por pantalla los diferentes elementos que la componen. procedimiento recorrer(E entero: inic} var entero: posic inicio “ 7 posic € inic : mientras posic <> 0 hacer ve { Recurrimos a un procedimiento, proc_escribir(...), He: para presentar por pantalla los campos del registro pasado como pardmetro } proc_escribir (m{posic] .elemento} posic © mlposic].sig fin_mientras “3 } fin_procedimiento Badsqueda de un determinadco elemento en una lista El procedimiento consultar informara sobre si un determinado elemento se encuentra 0 no en la lista, Ja posicién que ecupa dicho elemento en el array y la que ocupa el elemento anterior. Si la informa- cién se encontrara colocada en la lista de forma ordenada y creciente por el campo de biisqueda el pro- cedimiento de consulta podria ser el siguiente: procedimiento consultar(E entero: inic; S entero: posic, anterior; . E tipo_elemento: elemento; § légice: encontrado; E arr: m) inicio Dei ae bis anterior ¢ 0 -* posic © inic { Las funciones menor(...) ¢ igual(...)comparan los registros por un determinado campo} mientras menor (m[posic].elemento,elemento) y (posic <> 0) hacer anterior «+ posic posic <+ m[posic].sig fin mientras si igual (miposic].elemento,elemento} entonces encontrado « verdad * akin ts si_no a encontrado ¢ £also fin_ si . fin_procedimiento oo ae 462 = Fundamentos de programacién Funciones Ait Cuando implementames una lista enlazada utilizando arrays, necesitamos las siguientes funciones: légico funcién vacia(E entero: inic) inicio devolver(tinic = 0) fin_funcién légico funcién llena(E entero: vacio) inicio devolver(vacio = 0) fin_funcién 12.5. LISTAS CIRCULARES oo Las listas simplemente enlazadas no permiten a partir de un elemento acceder directamente a cual- quiera de los elementos que le preceden. En lugar de almacenar un puntero NULO en el campo SIG del ultimo elemento de ta lista, se hace que el tiltimo elemento apunte al primero o principio de la lis- ta, Este tipo de estructura se ilama /ista enlazada circular o simplemente fista circular (en algunos textos se les denomina listas en anillo). f PRIMERO INFO SIG INFO SIG INFO SIG INFO SIG [f—_ ef -+{_ et + +t + Las listas circulares presentan las siguientes ventajas respecto de las listas enlazadas simples: * Cada nodo de una lista circular es accesible desde cualquier otro nodo de ella. Es decir, dado un nodo se puede recorrer toda la lista completa. En una lista enlazada de forma simple sdlo es po- sible recorrerla por completo si se parte de su primer nodo. « Las operaciones de concatenacién y divisién de listas son mds eficaces con listas circulares. Los inconvenientes, por el contrarie, son: + Se pueden producir lazos o bucles infinitos. Una forma de evitar estos bucles infinitos es dispo- ner de un nodo especial que se encuentre permanentemente asociado a la existencia de la lista circular. Este nodo se denomina cabecera de la lista. . hd j CABECERA SIG INFO SIG INFO SIG INFO SIG — C = Figura 12.7, Nodo cabecera de la lista. Taugt fs Ei nodo cabecera puede diferenciarse de los otros nedos en una de las dos formas siguientes: * Puede tener un valor especial en su campo INFO que no es valido como datos de otros elementos. * Puede tener un indicador o bandera (fiag} que sefiale cuando es nodo cabecera. Estructuras dindmicas fineales de datos {pilas, colas y listas enlazadas) 463 El campo de la informacion del nodo cabecera no se utiliza, lo que se sefiala con el sombreado de dicho campo. Una lista enlazada circularmente vacia se representa como se muestra en la Figura 12.8. CABECERA Figura 12,8. Lista circular vacia. 12.6. LISTAS DOBLEMENTE ENLAZADAS En las listas lineales estudiadas anteriormente el recorrido de ellas s6lo podia hacerse en un Unico sen- tido: de izquierda a derecha (principio a final). En aumerosas ocasiones se necesita recorrer las Listas en ambas direcciones. Las listas que pueden recorrerse en ambas direcciones se denominan listas doblemente enlazadas. En estas listas cada node consta del campo INFO de datos y dos campos de enlace 0 punteros: AN- TERIOR(ANT) y SIGUIENTE (SIG) que apuntan hacia adelante y hacia atras (Fig. 12.9). Como cada elemento tiene dos punteros. una lista doblemente enlazada ocupa mas espacio en memoria que una lista simplemente enlazada para una misma cantidad de informacion. , La lista necesita dos punteros CABECERA y FIN* que apuntan hacia el primero y tltime nodo. La variable CABECERA y el puntero SIG permiten recorrer la lista en el sentido normal y la va- riable FIN y el puntero ANT permiten recorrerla en sentido inverso. © : NODO @ IZQUIERDA DERECHA “LL Fa tT Tt (b | Figura 12.9. Lista doblemente enlazada. capecene Campo INFO del nado n , FIN eo! [——— Campo ANT def nodo n . Cc Campa puntero SIG del nodon [x[¢}+4 Nodo n Figura 12.10. Lista doble. Como se ve en la Figura 12.11, una propiedad fundamental de las listas doblemente enlazadas es que para cualquier puntero P de la lista: ? Se adoptan estos términos a efectos de normalizacién, pero el lector puede utilizar TZQUIERDA y DERECHA, 464 = Fundamentos de programacion nodo [node[p]. sig].ant = p Job ogqersa 10 nodo [nodo[p]. ant.sig = p e Lay sig pm ant po pw sig Figura 12.11. . , 49.1800 2AT2I14 .8.St 12.6.1. Insercién . ind La insercién de un nodo a la derecha de un nodo especificado, cuya direccién esté dada por la varia- ble M, puede presentar varios casos: 1. La lista esta vacia; se indica mediante M = NULO y CABECERA y FIN son también NULO. Una insercién indica que CABECERA se debe fijar con la direccién del nuevo node y los cam- pos ANT y SIG también se establecen en NULO. 2. Insertar dentro de la lista: existe un elemento anterior y otro posterior de X. 3. Insertar a Ja derecha del nodo de la extwema derecha de la lista. Se requiere que el apuntador FIN sea modificado. capecera —+l/ ~ j= [of , /}— rin antes * M casccena—f/f | /\—em ar feces PAR CEP Ry x después Figura 12.12. Insercién en una lista doblamente enlazada. CABECERA — / después Estructuras dindmicas lineales de datos (pilas, colas y fistas enlazadas) 465 12.6.2. Eliminacién La operacién de eliminacion es directa. Si la lista tiene un simple node, entonces los punteros de los extremos izquierda y derecho aso- ciados a la lista se deben fijar en NULO. Si el nodo del extremo derecha de la lista es el sefialado para la eliminaci6n, la variable FIN debe modificarse para sefialar el predecesor del nodo que se va a bo- rrar de la lista. Si el nodo del extremo izquierdo de la lista es el que se desea borrar, la variable CA- BECERA debe modificarse para sefialar el elemento siguiente. La eliminacién se puede realizar dentro de la lista (Figura 12.14). CABECERA | ke a " Fi antes ANT (X) x aa rane: CABECERA—*// oy | FIN antes Figura 12.14. Eliminacidn de un nodo en una lista doblemente enlazada. sued BAEK 12.7. PILAS “lay Una pila (stack) es un tipo especial de lista lineal en la que la insercién y borrado de nuevos elemen- tos se realiza sdlo por un extremo que se denomina cima o tope (top). La pila es una estructura con numerosas analogias en la vida real: una pila de platos, una pila de monedas, una pila de cajas de zapatos, una pila de camisas, una pila de bandejas, ete. Una pila de bandejas Una pila de monedas Una pila de camisas Figura 12.15. Ejemplos de tipes de pilas. Dado que las operaciones de insertar y eliminar se realizan por un solo extremo (el superior), les elementos sélo pueden eliminarse en orden inverso al que se insertan en la pila. El ultimo elemento que se pone en la pila es el primero que se puede sacar; por ello, a estas estructuras se les conoce por él nombre de LIFO (last-in, first-out, dltimo en entrar, primero en salir). Lag operaciones mds usuales asociadas a las pilas son: "push" Meter, poner o apilar: operacién de insertar un elemento.en la pila. "pop" Sacar, quitar o desapilar: operacién de eliminar un elemento de fa pila. Las pilas se pueden representar en cualquiera de las ires formas de la Figura 12.16. 466 Fundamentos de programacion AAA 1 .S.0.87 BBB oo ccc nS Cima[ pop | - 2 L EEE 2 FFE I @) () AAA] BBB[CCC|DDD] EEE | FFF LT ] 7 2 3 7 8 9 N N ean 4 5 6 ae Cima —__1 fo) * Figura 12.16. Representacién de las pilas. Para representar una pila St, se debe definir un vector con un determinado tamaiio (longitud md- xima): war array [1..n] de : St Se considerard un elemento entero P como el puntero de la pila (stack pointer). P es el subindice del array correspondiente al elemento cima de la pila (esto es, el que ocupa la tiltima posicidn). Si la pila esta vacia,P = 0. Parte no utilizada actualmente de ja pila 1 2 3 4 p-1p n-2n-t oo Longitud Cima maxima de la (puntero de Ia pila) pila En principio, la pila esta vacia y el puntero de la pila o CIMA esta a cero. Al meter un elemento en la pila, se incrementa el puntero en una unidad. Al sacar un elemento de la pila se decrementa en una unidad el puntero, Al manipular ena pila se deben realizar algunas comprobaciones. En una pila vacia no se pue- den sacar datos (P = 0). Si la pila se implementa con un array de tamaiio fijo, se puede Ilenar cuando P =n (n, longitud total de la pila) y el intento de introducir mas elementos en la pila producir4 un desbordamiento de ia pila. Idealmente una pila puede contener un nimero ilimitado de elementos y no producir nunca des- bordamiento. En la practica, sin embargo, el espacio de almacenamiento disponible es finito. La.co- dificacién de una pila requiere un cierto equilibrio, ya que si la longitud maxima de la pila es dema- _Siado grande se gasta mucha memoria, mientras que un valor pequefio de la longitud maxima producira desbordamientos frecuentes. Para trabajar facilmente con pilas es conveniente disefiar subprogramas de poner (push) y quitar (pop) elementos. También es necesario con frecuencia comprobar si la pila est vacia; esto puede con- Estructuras dindmicas lineales de datos (pilas, colas y listas enlazadas) == 467 seguirse con una variable o funcién booleana VACIA, de modo que cuande su valor sera verdadero la pila esta vacia y falso en caso contrario. -; 1835M P= CIMA Puntero de la pila. VACTA Funcién booleana «pila vacta». PUSH Subprograma para afiadir, poner o insertar elementos. POP Subprograma para eliminar o quitar elementos. LONGMAX Longitud mdxima de la pila. $(i) Elemento i-ésimo de ta pila S. x Elemento a afiadir/quitar de ta pila. Tmplementacién con punteros Si el lenguaje tiene punteres, deberemos implementar las pilas con punteros. Para la manipulacién de una pila mediante punteros deberemos disefiar los siguientes procedi- mientos y/o funciones: inicializar o crear, apilar ometer, desapilaro sacar, con-_ sultarCima y Vacia, algoritine pilas_con_punteros tipo puntero_a nodo: punt registro : tipo_elemento f fin registro registro : nodo tipo_elemento : elemento punt : cima fin_registro SOK | var ——~ punt : cima elemento : tipo_elemento inicio inicializar(cima} fin proecedimiento inicializar($ punt: cima) inicio cima — nulo fin_procedimiento légico funcién vacia{E punt: cima) inicio . devolver (cima = nulo) fin_funcién oe asmin “FE of procedimiente consultarCima(B punt: cima; 6 tipo_elemento: elemento) of inicio elemento ¢ cima>.elemento fin _procedimiento 468 Fundamentos de programacién Los elementos se incorporan siempre por un extremo, cima. a 2 ull Meter(cima, elemento) g cima cima > elemento cima 1° | 2° a auxi adh L=[J*b]"" zzz auxi 1 cima—7 elemento cima auxi 62 cima7 elemento cima b= om Te] vn C= Te] 1° cima apunta al ultimo elemento de Ia pila. 2° reservar (auxi). 3.° Introducimos la informacion en auxi—. elemento. 4° Hacemes que auxi—.cima apunte a donde cima. 3.2 Cambiamos cima para que apunte donde auxi. 6.° La pila tiene un elemento mis. — ; MAE RE ne Estructuras dinamicas lineales de datos (pilas, colas y listas enlazadas) 469 procedimiento meter(E/S punt: cima; EB tipo_elemento: elemento) var punt: auxi inicio reservar (auxi) auxim.elemento <— elemento auxi~.cima <— cima Ww cima © auxi : eh eS fin_procedimiento . . . walaonl Los elementos se recuperan en orden inverso a como fueron introducidos s i lement. a“ acar(cima, elemento) stig cima cima > elemento cima cima S+cima > elemento cima auxi cima > elemento cima Low To | [me |e | os 1° cima apunta al Ultimo elemento de la pila me 2.° Hacemos que auxi apunte a donde apuntaba cima 3.° Y que cima pase a apuntar a donde cima—.cima 4° liberar(auxi) 5.° La pila tiene un elemento menos ee procedimiento sacar(E/S punt:cima; S&S tipo_elemento: elemento) + fee var punt: auxi 470 = Fundamentos de programacién inicio auxi «— cima elemento <— cima >,elemento cima ~ cima —.cima Liberar (auxi) {liberar ¢8 un procédimiento para la eliminacién de variables dindmicas} fin_procedimiento Implemeniacién con arrays ahatbsqo1g - 80 a ving otoiat and Necesitaremos un array y una variable numérica cima que apunte al ultimo elemento colocado en la pila. La insercién o extraccién de un elemento se realizara siempre por la parte superior. Su implementacién mediante arrays limita el maximo numero de elementos que la pila puede con- tener y origina Ja necesidad de una funcidn mas. Llena(...) de resultado légico Inicializar (cima) cima ¢ 0 cima — 1) XxKXKXX» const Max = tipo registro: tipc_elemento fin_regiatro array[{1..Max] de tipo_elemento: arr var entero “ : cima . arr zp tipo_elemento : elemento inicio inicializaricima) fin Meter {cima,p, elemento) XKKAKKXX Sacar (cima,p, elemento) o ag "é of *2 siakbeoorg “BY, Estructuras dinémicas lineales de datos (piles, colas y listas enlazadas) = 471 procedimiento inicializar($ entero: cima} inicio cima © 0 fin_procedimiento légico funcién vacia(B entero: cima) 1 alec inicio : , ei cima = 0 entonces aq | devolver (verdad) _f- si_no devolver (falso} ts fin_ai fin _funcién légico funcién llena(E entero: cima} ae inicio ei cima = Max entonces devolver (verdad) si_no =. ALOE sit devolver (falso) > Sey os ee fin_ai . : fin_funcién de as pitas e- procedimiento consultarCima(B entero: cima; E arr:ps sy ty ¥ & tipo_elemento: elemento} : . inicio . elemento © p(cima] fin_procedimiento procedimiento meter(H/S entero: cima; E/S arr: Pp: E tipo_elemento: elemento) inicio cima « cima + 1 plcima] © elemento fin_procedimiento procedimiento sacar(E/S entero: cima; E arr: p; .. ; . S$ tipo_elemento: elemento) pees a inicio é elemento < p[cima] aban cima © cima - 1 wep ey owt fin_procedimiento — 12.7.1. Aplicaciones de las pilas 4 Las pilas son utilizadas ampliamente para solucionar una amplia variedad de problemas. Se utilizan en compiladores, sistemas operatives y en programas de aplicacion. Veamos algunas de las aplicacio- hes mds interesantes. Llamadas a subprogramas on Cuando dentro de un programa se realizan Ilamadas a subprogramas, el programa principal debe re- cordar el lugar donde se hizo la Hamada, de modo que pueda retornar alli cuando el subprograma se haya terminado de ejecutar. 472 — Fundamentos de programacién Supongames que tenemos tres subprogramas Ilamados A, B y C, y supongamos también que A in- voca a B y B invoca a C, Entonces B no terminard su trabajo hasta que C haya terminado y devuelto su control a B. De modo similar, A es ef primero que arranca su ejecucién, pero es el uiltimo que la termina, tras la terminacién y retorne de B. Esta eperacion se consigue disponiendo las direcciones de retorno en una pila. Programa principal Subprograma A Zz Puntero de pila ¥ Subprograma B [xd sheet Subprograma C Pila de direcciones de retorno amide oc Programa principal Mos omia ke llamar_a A — subprograma A tevioveb , direccion x ----» on_te + stevioved : fin nos : : i ' llamar_a B—* subprograma B 21g Da : direccion y aad | meee cee ol i : ° i olotot fin_subproegrama A llamar a C —— subprograma C ‘ ‘ ‘ pane enn dee: Cuando un subprograma termina, debe retornar a la direccidén siguiente a la instruccién que le Ila- m6 (llamar_a). Cada vez que se invoca un subprograma, Ia direccién siguiente (x, y 0 z) se intro- duce en Ja pila. El vaciado de la pila se realizara por los sucesivos retornos, decrementandose el] pun- tero de pila queda libre siempre apuntando a Ia siguiente direccién de retorno. © Puntero de pila (P) . . f z PoP vingoilqa .t yo HP "st © x x 4 | JP Retomo a Retomo a Retorno a subprograma B subprograma A programa principal Ejemplo 12.6 Se desea leer un texto y separar los caracteres letras, digitos y restantes caracteres para ser ; utilizados posteriormente. e &structuras dindmicas lineaies de datas (pilas, colas y listas eniazadas} 473 Utilizaremos tres pilas (LETRAS, DIGITOS, GTROSCAR) para contener los diferentes tipos de caracteres. El proceso consiste en leer cardcter a caracter, comprobar el tipo de cardcter y segiin el re- sultado introducirlo en su pila respectiva. aigoritmo lecturacaracter lp) bee Loew ¢onst Max = , tipo .-f} ystats ev array [1..Max]) de caradcter:pila var . mile ef apr of nig entero : Cimal, cima2, cima3 pila : pilaletras, piladigitos, pilaotroscaracteres cardcter : elemento : inicio Stee est nety crear {cimal} crear (cima2} crear (cima) elemento ~ leercar mientras (codigo(elemento}<> 26) y mo llena (cimal) y no llena(cima2}y no Llena {(cima3} hacer {saldremos del bucle en cuanto se llene alguna de las pilas o pulsemos *Z} si {elemento >= ‘A') y {elemente <= 'Z') o {elemento >= ‘a'} y {elemento >= 'z')entonces Meter (cimal, pilaletras, elemento) si_no Bi (elemento>= '0') y (elemento<='9'} entonces meter (cima2, piladigitos, elemento) si_no t meter (cima3, pilaotroscaracteres, elemento} fin _si fin_si elemento © leercar fin_mientras fin ° ineearqeR .P.8.sr procedimiento crear {S entero: cima) inicio alos eo] cima ¢ 0 1 92: £in_procedimiento on shed légico funcién llena (E entero: cima} ; inicio sot eeecereesece - develver (cima = Max) ' fin_funcién yt procedimiento meter(E/S entero: cima: E/S tipo_elemento: elemento) inicio © t cima « cima+1 , p [cima] « elemento fin_procedimientc 474 Fundamentos de programacion 12.8. COLAS Shon! Las colas son otro tipo de estructura lineal de datos similar a las pilas, diferencidndose de ellas en el modo de insertar/eliminar elementos. : Una cola (queue) es una estructura lineal de datos te hs 2 var array [1..n] de : ¢ ogizs en la que las efiminaciones se realizan al principio de la lista, frente (front), y las inserciones se reali- zan en el otro extrema, final (rear), En las colas el elemento que entré el primero sale también el pri- mero; por ello se conoce como listas FIFO (first-in, first-out, «primero en entrar, primero en salir»). Asi, pues, la diferencia con las pilas reside en el modo de entrada/salida de datos; en las colas las in- serciones de realizan al final de la lista, no al principio. Por eilo las colas se usan para almacenar da- tos que necesitan ser procesados seguin el orden de legada. > 2 xf] x[2}_ x[3] xin— 4] x{n] 5 eins {TT Ts TTT ern + ame SEE Frente Final ft } En la vida real se tienen ejemplos numerosos de colas: la cola de un autobus, la cola de un cine, una caravana de coches en una calle, etc. En todas ellas el primer elemento (pasajero, coche, etc.) que llega es el primero que sale. En informatica existen también numerosas aplicaciones de las colas. Por ejemplo, en un sistema de tiempo compartido suele haber un procesador central y una serie de periféricos compartidog: dis- cos, impresoras, etc. Los recursos se comparten por los diferentes usuarios y se utiliza una cola para almacenar los programas © peticiones de los diferentes usuarios que esperan su turno de ejecucion. El procesador central atiende —normalmente— por riguroso orden de llamada del usuario; por tanto, to- das las Hamadas se almacenan en una cola. Existe otra aplicacion muy utilizada que se denomina cola de prioridades; en ella el procesador central no atiende por riguroso orden de llamada, aqui el proce- sador atiende por prioridades asignadas por el sistema o bien por el usuario, y sélo dentro de las peti- ciones de igual prioridad se producird una cola. 12.8.1. Representacion de las colas ’ Las colas se pueden representar por listas enlazadas o por arrays. Se necesitan dos punteros: frente(f) y finai(r), y la lista o array de n elementos (LONGMAX). Parte no utilizada de la lista Cola Parte no utilizada de fa lista i 2 f-1 E fed r-1 roocrel si la cola esta vacia frente = nulo 9 bien f<0 eliminar elementos frente — frente +1 9 bien fef-1 afiadir elementos final — finat + 1 0 bier rere]

También podría gustarte