7 IMPLEMENTACION : LISTAS DOBLEMENTE ENLAZADAS
\r
9 ALMACENAMIENTO : CURSORES
\r
17 { ACLARACIONES : implementamos tambien aca los cursores porque son para estos nodos en particular }
\r
19 Este c¢digo esta basado en la implementacion de listas simples dada
\r
27 { usa las funciones generales de TDAs }
\r
33 { maximo tamano del cursor }
\r
35 const LSC_MAX_CURSOR = 100;
\r
39 { tipos propios de la lista para definir el cursor }
\r
43 LSC_puntero = Integer;
\r
49 LSC_nulo : LSC_puntero = 0;
\r
59 Elem : Tipo_Elem; {definido en TDA_GRAL}
\r
61 Sig,Ant : LSC_puntero;
\r
67 { ahora le toca definir el cursor }
\r
71 almacenamiento : array [ 1 .. LSC_MAX_CURSOR ] of LSC_Nodo;
\r
73 siguientes : array [ 1 .. LSC_MAX_CURSOR ] of LSC_Puntero;
\r
75 anteriores : array [ 1 .. LSC_MAX_CURSOR ] of LSC_Puntero;
\r
77 {decia: primero_dispo : TTDA_Puntero;}
\r
78 primero_dispo: LSC_puntero;
\r
86 LSC_Lista_Simple_C = RECORD
\r
90 primero: LSC_puntero;
\r
92 corriente : LSC_puntero;
\r
98 LSC_movimiento = (LSC_primero, LSC_ultimo, LSC_siguiente,LSC_anterior );
\r
112 PROCEDURE LSC_Inicializar ( VAR l: LSC_Lista_Simple_C );
\r
114 FUNCTION LSC_vacio( l: LSC_Lista_Simple_C): BOOLEAN;
\r
116 FUNCTION LSC_lleno( l: LSC_Lista_Simple_C): BOOLEAN;
\r
120 PROCEDURE LSC_elem_cte ( l: LSC_Lista_Simple_C; VAR e: Tipo_Elem);
\r
122 PROCEDURE LSC_modif_cte ( VAR l: LSC_Lista_Simple_C; VAR e: Tipo_Elem);
\r
124 PROCEDURE LSC_mover_cte ( VAR l: LSC_Lista_Simple_C; m: LSC_movimiento; VAR error: BOOLEAN );
\r
126 PROCEDURE LSC_borrar_cte ( VAR l: LSC_Lista_Simple_C );
\r
128 PROCEDURE LSC_insertar ( VAR l: LSC_Lista_Simple_C; m: LSC_movimiento; var e: Tipo_Elem );
\r
130 PROCEDURE LSC_vaciar ( VAR l: LSC_Lista_Simple_C );
\r
132 PROCEDURE LSC_copiar ( a: LSC_Lista_Simple_C; VAR b: LSC_Lista_Simple_C );
\r
140 { CURSORES DE ESTA IMPLEMENTACION }
\r
142 { ========================================================================== }
\r
144 { inicializar el almacenamiento }
\r
146 { PRE : 'almac' no esta inicializado }
\r
148 { POST: 'almac' esta inicializado y vacio }
\r
150 procedure LSC_Almac_Inicializar( VAR almac : LSC_Almac );
\r
152 var i : LSC_Puntero;
\r
156 almac.primero_dispo := 1;
\r
158 { almac.anteriores[1] := LSC_Nulo;}
\r
160 for i := 1 to LSC_MAX_CURSOR - 1 do
\r
164 almac.siguientes[i] := i + 1;
\r
165 { almac.anteriores[i+1] := i;}
\r
169 almac.siguientes[LSC_MAX_CURSOR] := LSC_Nulo;
\r
175 { ========================================================================== }
\r
177 { saber si hay lugar para reservar un nuevo elemento en el almacenamiento }
\r
179 { PRE : 'almac' esta inicializado }
\r
181 { POST: si hay lugar en 'almac' para un nuevo elemento,
\r
183 entonces retorna TRUE y sino FALSE }
\r
184 {MODIFICACION: Retornaba false si NO habia lugar. Ademas el
\r
185 parametro ahora viene por referencia.}
\r
187 function LSC_Almac_HayLugar( var almac : LSC_Almac ): boolean;
\r
191 LSC_Almac_HayLugar := NOT (almac.primero_dispo = LSC_Nulo);
\r
197 { ========================================================================== }
\r
199 { el pedido de un nuevo elemento al almacenamiento }
\r
201 { PRE : 'almac' esta inicializado }
\r
203 { POST: si hay lugar en 'almac' para un nuevo elemento,
\r
205 entonces 'puntero' tiene una referencia a un nuevo elemento del almacenamiento
\r
207 sino 'puntero' tiene el valor TTDA_Nulo }
\r
209 procedure LSC_Almac_Reservar( VAR almac : LSC_Almac; VAR puntero : LSC_Puntero );
\r
213 if not LSC_Almac_HayLugar( almac )
\r
217 puntero := LSC_Nulo
\r
221 puntero := almac.primero_dispo;
\r
223 almac.primero_dispo := almac.siguientes[ puntero ];
\r
231 { ========================================================================== }
\r
233 { liberar un elemento del almacenamiento }
\r
235 { PRE : 'almac' esta inicializado y 'puntero' fue pedido al almacenamiento }
\r
237 { POST: 'almac' libero el nodo apuntado por 'puntero' y 'puntero' vale TTDA_Nulo }
\r
239 procedure LSC_Almac_Liberar( VAR almac : LSC_Almac; VAR puntero : LSC_Puntero );
\r
243 almac.siguientes[ puntero ] := almac.primero_dispo;
\r
245 almac.primero_dispo := puntero;
\r
247 puntero := LSC_Nulo;
\r
253 { ========================================================================== }
\r
255 { acceder al elemento del almacenamiento apuntado por un puntero }
\r
257 { PRE : 'almac' esta inicializado y 'puntero' fue pedido al almacenamiento }
\r
259 { POST: 'elemento' tiene una copia del elemento apuntado por 'puntero' }
\r
261 procedure LSC_Almac_Acceder( almac : LSC_Almac; puntero : LSC_Puntero; VAR elemento : LSC_Nodo );
\r
265 elemento := almac.almacenamiento[ puntero ];
\r
271 { ========================================================================== }
\r
273 { modificar el elemento del almacenamiento apuntado por un puntero }
\r
275 { PRE : 'almac' esta inicializado y 'puntero' fue pedido al almacenamiento }
\r
277 { POST: el elemento de 'almac' apuntado por 'puntero' tiene una copia de 'elemento' }
\r
279 procedure LSC_Almac_Modificar( VAR almac : LSC_Almac; puntero : LSC_Puntero; elemento : LSC_Nodo );
\r
283 almac.almacenamiento[ puntero ] := elemento;
\r
293 { Estas son los dos procedimientos principales de la aplicación }
\r
297 PROCEDURE LSC_Inicializar ( VAR l: LSC_Lista_Simple_C );
\r
301 LSC_Almac_Inicializar( l.almac );
\r
303 l.primero := LSC_Nulo;
\r
305 l.corriente := LSC_Nulo;
\r
311 FUNCTION LSC_vacio( l: LSC_Lista_Simple_C): BOOLEAN;
\r
315 LSC_vacio := ( l.Primero = LSC_Nulo);
\r
321 FUNCTION LSC_lleno( l: LSC_Lista_Simple_C): BOOLEAN;
\r
325 LSC_lleno := not LSC_Almac_HayLugar( l.almac );
\r
331 PROCEDURE LSC_elem_cte ( l: LSC_Lista_Simple_C; VAR e: Tipo_Elem);
\r
337 { accedo al almacenamiento por el nodo corriente }
\r
339 LSC_Almac_Acceder ( l.almac, l.Corriente, n );
\r
343 { y se lo asigno al parametro }
\r
351 PROCEDURE LSC_modif_cte ( VAR l: LSC_Lista_Simple_C; VAR e: Tipo_Elem);
\r
357 { accedo al almacenamiento por el nodo corriente }
\r
359 LSC_Almac_Acceder ( l.almac, l.Corriente, n );
\r
363 { y la asigno al parametro }
\r
369 { y modifico el almacenamiento }
\r
371 LSC_Almac_Modificar ( l.almac, l.Corriente, n );
\r
379 PROCEDURE LSC_mover_cte ( VAR l: LSC_Lista_Simple_C; m: LSC_movimiento; VAR error: BOOLEAN );
\r
381 VAR n : LSC_Nodo; prueba: integer ;
\r
391 l.Corriente := l.Primero;
\r
396 { accedo al almacenamiento por el nodo corriente }
\r
398 LSC_Almac_Acceder ( l.almac, l.Corriente, n );
\r
402 {modificado, decia n.siguiente}
\r
403 IF n.ant = LSC_Nulo
\r
412 l.corriente := n.ant;
\r
419 { accedo al almacenamiento por el nodo corriente }
\r
420 LSC_Almac_Acceder ( l.almac, l.Corriente, n );
\r
424 {modificado, decia n.siguiente}
\r
425 IF n.sig = LSC_Nulo
\r
434 {decia: l.corriente := n.siguiente;}
\r
435 l.corriente := n.sig;
\r
439 {Implementacion recursiva de mover al ultimo,para listas
\r
440 doblemente enlazadas.}
\r
444 { accedo al almacenamiento por el nodo corriente }
\r
447 LSC_mover_cte ( l, lsc_siguiente, error);
\r
449 IF error <> true then
\r
451 LSC_mover_cte ( l, lsc_ultimo, error);
\r
463 PROCEDURE LSC_borrar_cte ( VAR l: LSC_Lista_Simple_C );
\r
467 tmp,tmp2 : LSC_Nodo;
\r
469 tmpp : LSC_Puntero;
\r
473 if l.corriente = l.primero then begin
\r
475 LSC_Almac_Acceder( l.almac, l.primero, n );
\r
477 l.primero := n.Sig;
\r
479 LSC_Almac_Liberar( l.almac, l.corriente );
\r
481 l.corriente := l.primero;
\r
483 {Asigno a l.primero^.ant un valor LSC_Nulo, en las siguientes 3 lineas}
\r
485 LSC_Almac_Acceder( l.almac, l.primero, tmp );
\r
487 tmp.ant:= LSC_Nulo;
\r
489 LSC_Almac_Modificar( l.almac, l.primero, tmp );
\r
497 LSC_Almac_Acceder( l.almac, tmpp, tmp );
\r
499 while( tmp.sig <> l.corriente ) do begin
\r
503 LSC_Almac_Acceder( l.almac, tmpp, tmp );
\r
507 LSC_Almac_Acceder( l.almac, l.corriente, n );
\r
511 LSC_Almac_Modificar( l.almac, tmpp, tmp ); {creo que esto faltaba}
\r
513 {Agregado: este IF modifica el anterior del siguiente, siempre
\r
514 que corriente no sea el ultimo}
\r
516 IF n.sig <> LSC_Nulo THEN
\r
519 LSC_Almac_Acceder( l.almac, n.sig, tmp2 );
\r
523 LSC_Almac_Modificar( l.almac, tmp.sig, tmp2 );
\r
526 LSC_Almac_Liberar( l.almac, l.corriente );
\r
528 l.corriente := tmpp;
\r
536 PROCEDURE LSC_insertar ( VAR l: LSC_Lista_Simple_C; m: LSC_movimiento; var e: Tipo_Elem );
\r
544 ant,sig : LSC_Nodo;
\r
552 LSC_Almac_Reservar( l.almac, np );
\r
562 {Agregado: cambiar l.primero^.ant a el nuevo nodo}
\r
563 IF l.primero <> LSC_NULO THEN
\r
565 LSC_Almac_Acceder( l.almac, l.primero, ant );
\r
569 LSC_Almac_Modificar( l.almac, l.primero, ant );
\r
572 n.sig := l.primero;
\r
574 LSC_Almac_Modificar ( l.almac, np, n );
\r
585 LSC_Almac_Acceder( l.almac, l.corriente, sig );
\r
587 n.sig := l.corriente;
\r
593 IF n.ant <> lsc_nulo then begin
\r
595 LSC_Almac_Acceder( l.almac, n.ant, ant );
\r
599 LSC_Almac_Modificar( l.almac, n.ant, ant );
\r
603 LSC_Almac_Modificar( l.almac, np, n );
\r
605 LSC_Almac_Modificar( l.almac, l.corriente, sig );
\r
607 If l.corriente = L.primero then l.primero:= np;
\r
617 LSC_Almac_Acceder( l.almac, l.corriente, ant );
\r
620 n.ant := l.corriente;
\r
624 {Agregado: cambia n.sig^.ant a el nuevo nodo}
\r
626 IF n.sig <> lsc_nulo then begin
\r
628 LSC_Almac_Acceder( l.almac, n.sig, sig );
\r
632 LSC_Almac_Modificar( l.almac, n.sig, sig );
\r
636 LSC_Almac_Modificar( l.almac, np, n );
\r
638 LSC_Almac_Modificar( l.almac, l.corriente, ant );
\r
655 PROCEDURE LSC_vaciar ( VAR l: LSC_Lista_Simple_C );
\r
657 VAR np : LSC_Puntero;
\r
663 LSC_Inicializar(l); {esta es otra forma de vaciar una lista, ya que la
\r
664 original no estoy seguro de que funciona}
\r
667 (* np := l.primero;
\r
669 while( np <> LSC_Nulo ) do begin
\r
671 LSC_Almac_Acceder( l.almac, np, n );
\r
673 LSC_Almac_Liberar( l.almac, np );
\r
679 l.primero := LSC_Nulo;
\r
681 l.corriente := LSC_Nulo;
\r
688 { pre: 'a' y 'b' estan creadas y 'b' esta vacia }
\r
690 { POST: 'b' tiene una copia de los elementos de 'a' y el corriente esta en el primero }
\r
692 PROCEDURE LSC_copiar ( a : LSC_Lista_Simple_C; VAR b : LSC_Lista_Simple_C );
\r
694 VAR np,mp,tmpp : LSC_Puntero;
\r
700 { if a.primero = LSC_Nulo then return; {return no existe}
\r
702 if a.primero = LSC_Nulo then exit;
\r
707 LSC_Almac_Acceder( a.almac, np, n );
\r
711 LSC_Almac_Reservar( b.almac, mp );
\r
719 m.ant := n.ant; {agregado para listas dobles}
\r
722 while( n.sig <> LSC_Nulo ) do begin
\r
726 LSC_Almac_Reservar( b.almac, tmpp );
\r
730 LSC_Almac_Modificar( b.almac, mp, m );
\r
735 LSC_Almac_Acceder( a.almac, np, n );
\r
750 LSC_Almac_Modificar( b.almac, mp, m );
\r