]> git.llucax.com Git - z.facultad/75.41/material.git/blob - tp_ejemplo/ldoblec.pas
Se expanden keywords del svn.
[z.facultad/75.41/material.git] / tp_ejemplo / ldoblec.pas
1 unit ldoblec;\r
2 \r
3 \r
4 \r
5 {\r
6 \r
7         IMPLEMENTACION : LISTAS DOBLEMENTE ENLAZADAS\r
8 \r
9         ALMACENAMIENTO : CURSORES\r
10 \r
11 \r
12 \r
13 }\r
14 \r
15 \r
16 \r
17 { ACLARACIONES : implementamos tambien aca los cursores porque son para estos nodos en particular }\r
18 (*\r
19 Este c¢digo esta basado en la implementacion de listas simples dada\r
20 por la c tedra.\r
21 *)\r
22 \r
23 interface\r
24 \r
25 \r
26 \r
27 { usa las funciones generales de TDAs }\r
28 \r
29 uses tda_gral;\r
30 \r
31 \r
32 \r
33 { maximo tamano del cursor }\r
34 \r
35 const LSC_MAX_CURSOR = 100;\r
36 \r
37 \r
38 \r
39 { tipos propios de la lista para definir el cursor }\r
40 \r
41 TYPE\r
42 \r
43         LSC_puntero = Integer;\r
44 \r
45 \r
46 \r
47 const\r
48 \r
49    LSC_nulo : LSC_puntero = 0;\r
50 \r
51 \r
52 \r
53 type\r
54 \r
55 \r
56 \r
57         LSC_nodo = RECORD\r
58 \r
59                 Elem : Tipo_Elem;   {definido en TDA_GRAL}\r
60 \r
61                 Sig,Ant : LSC_puntero;\r
62 \r
63         END;\r
64 \r
65 \r
66 \r
67    { ahora le toca definir el cursor }\r
68 \r
69    LSC_Almac = record\r
70 \r
71       almacenamiento : array [ 1 .. LSC_MAX_CURSOR ] of LSC_Nodo;\r
72 \r
73       siguientes     : array [ 1 .. LSC_MAX_CURSOR ] of LSC_Puntero;\r
74 \r
75       anteriores     : array [ 1 .. LSC_MAX_CURSOR ] of LSC_Puntero;\r
76 \r
77       {decia: primero_dispo  : TTDA_Puntero;}\r
78       primero_dispo: LSC_puntero;\r
79 \r
80    end;\r
81 \r
82 \r
83 \r
84 \r
85 \r
86    LSC_Lista_Simple_C = RECORD\r
87 \r
88                 almac : LSC_Almac;\r
89 \r
90                 primero: LSC_puntero;\r
91 \r
92                 corriente : LSC_puntero;\r
93 \r
94         END;\r
95 \r
96 \r
97 \r
98         LSC_movimiento = (LSC_primero, LSC_ultimo, LSC_siguiente,LSC_anterior );\r
99 \r
100 \r
101 \r
102 \r
103 \r
104 { ========= }\r
105 \r
106 { INTERFACE }\r
107 \r
108 \r
109 \r
110 \r
111 \r
112 PROCEDURE LSC_Inicializar ( VAR l: LSC_Lista_Simple_C );\r
113 \r
114 FUNCTION  LSC_vacio( l: LSC_Lista_Simple_C): BOOLEAN;\r
115 \r
116 FUNCTION  LSC_lleno( l: LSC_Lista_Simple_C): BOOLEAN;\r
117 \r
118 \r
119 \r
120 PROCEDURE LSC_elem_cte ( l: LSC_Lista_Simple_C; VAR e: Tipo_Elem);\r
121 \r
122 PROCEDURE LSC_modif_cte ( VAR l: LSC_Lista_Simple_C; VAR e: Tipo_Elem);\r
123 \r
124 PROCEDURE LSC_mover_cte ( VAR l: LSC_Lista_Simple_C; m: LSC_movimiento; VAR error: BOOLEAN );\r
125 \r
126 PROCEDURE LSC_borrar_cte ( VAR l: LSC_Lista_Simple_C );\r
127 \r
128 PROCEDURE LSC_insertar ( VAR l: LSC_Lista_Simple_C; m: LSC_movimiento; var e: Tipo_Elem );\r
129 \r
130 PROCEDURE LSC_vaciar ( VAR l: LSC_Lista_Simple_C );\r
131 \r
132 PROCEDURE LSC_copiar ( a: LSC_Lista_Simple_C; VAR b: LSC_Lista_Simple_C );\r
133 \r
134 \r
135 \r
136 implementation\r
137 \r
138 \r
139 \r
140 { CURSORES DE ESTA IMPLEMENTACION }\r
141 \r
142 { ========================================================================== }\r
143 \r
144 {  inicializar el almacenamiento }\r
145 \r
146 { PRE : 'almac' no esta inicializado  }\r
147 \r
148 { POST: 'almac' esta inicializado y vacio }\r
149 \r
150 procedure LSC_Almac_Inicializar( VAR almac : LSC_Almac );\r
151 \r
152 var i : LSC_Puntero;\r
153 \r
154 begin\r
155 \r
156    almac.primero_dispo := 1;\r
157 \r
158 {   almac.anteriores[1] := LSC_Nulo;}\r
159 \r
160    for i := 1 to LSC_MAX_CURSOR - 1 do\r
161 \r
162    begin\r
163 \r
164       almac.siguientes[i] := i + 1;\r
165 {      almac.anteriores[i+1] := i;}\r
166 \r
167    end;\r
168 \r
169    almac.siguientes[LSC_MAX_CURSOR] := LSC_Nulo;\r
170 \r
171 end;\r
172 \r
173 \r
174 \r
175 { ========================================================================== }\r
176 \r
177 {  saber si hay lugar para reservar un nuevo elemento en el almacenamiento }\r
178 \r
179 { PRE : 'almac' esta inicializado  }\r
180 \r
181 { POST: si hay lugar en 'almac' para un nuevo elemento,\r
182 \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
186 \r
187 function LSC_Almac_HayLugar( var almac : LSC_Almac ): boolean;\r
188 \r
189 begin\r
190 \r
191    LSC_Almac_HayLugar := NOT (almac.primero_dispo = LSC_Nulo);\r
192 \r
193 end;\r
194 \r
195 \r
196 \r
197 { ========================================================================== }\r
198 \r
199 {  el pedido de un nuevo elemento al almacenamiento }\r
200 \r
201 { PRE : 'almac' esta inicializado  }\r
202 \r
203 { POST: si hay lugar en 'almac' para un nuevo elemento,\r
204 \r
205             entonces 'puntero' tiene una referencia a un nuevo elemento del almacenamiento\r
206 \r
207             sino 'puntero' tiene el valor TTDA_Nulo }\r
208 \r
209 procedure LSC_Almac_Reservar( VAR almac : LSC_Almac; VAR puntero : LSC_Puntero );\r
210 \r
211 begin\r
212 \r
213    if not LSC_Almac_HayLugar( almac )\r
214 \r
215    then\r
216 \r
217       puntero := LSC_Nulo\r
218 \r
219    else begin\r
220 \r
221       puntero := almac.primero_dispo;\r
222 \r
223       almac.primero_dispo := almac.siguientes[ puntero ];\r
224 \r
225    end;\r
226 \r
227 end;\r
228 \r
229 \r
230 \r
231 { ========================================================================== }\r
232 \r
233 {  liberar un elemento del almacenamiento }\r
234 \r
235 { PRE : 'almac' esta inicializado y 'puntero' fue pedido al almacenamiento  }\r
236 \r
237 { POST: 'almac' libero el nodo apuntado por 'puntero' y 'puntero' vale TTDA_Nulo }\r
238 \r
239 procedure LSC_Almac_Liberar( VAR almac : LSC_Almac; VAR puntero : LSC_Puntero );\r
240 \r
241 begin\r
242 \r
243    almac.siguientes[ puntero ] := almac.primero_dispo;\r
244 \r
245    almac.primero_dispo := puntero;\r
246 \r
247    puntero := LSC_Nulo;\r
248 \r
249 end;\r
250 \r
251 \r
252 \r
253 { ========================================================================== }\r
254 \r
255 {  acceder al elemento del almacenamiento apuntado por un puntero }\r
256 \r
257 { PRE : 'almac' esta inicializado y 'puntero' fue pedido al almacenamiento  }\r
258 \r
259 { POST: 'elemento' tiene una copia del elemento apuntado por 'puntero' }\r
260 \r
261 procedure LSC_Almac_Acceder( almac : LSC_Almac; puntero : LSC_Puntero; VAR elemento : LSC_Nodo );\r
262 \r
263 begin\r
264 \r
265    elemento := almac.almacenamiento[ puntero ];\r
266 \r
267 end;\r
268 \r
269 \r
270 \r
271 { ========================================================================== }\r
272 \r
273 {  modificar el elemento del almacenamiento apuntado por un puntero }\r
274 \r
275 { PRE : 'almac' esta inicializado y 'puntero' fue pedido al almacenamiento }\r
276 \r
277 { POST: el elemento de 'almac' apuntado por 'puntero' tiene una copia de 'elemento' }\r
278 \r
279 procedure LSC_Almac_Modificar( VAR almac : LSC_Almac; puntero : LSC_Puntero; elemento : LSC_Nodo );\r
280 \r
281 begin\r
282 \r
283    almac.almacenamiento[ puntero ] := elemento;\r
284 \r
285 end;\r
286 \r
287 \r
288 \r
289 \r
290 \r
291 \r
292 \r
293 { Estas son los dos procedimientos principales de la aplicación }\r
294 \r
295 \r
296 \r
297 PROCEDURE LSC_Inicializar ( VAR l: LSC_Lista_Simple_C );\r
298 \r
299 BEGIN\r
300 \r
301    LSC_Almac_Inicializar( l.almac );\r
302 \r
303    l.primero := LSC_Nulo;\r
304 \r
305    l.corriente := LSC_Nulo;\r
306 \r
307 END;\r
308 \r
309 \r
310 \r
311 FUNCTION LSC_vacio( l: LSC_Lista_Simple_C): BOOLEAN;\r
312 \r
313 BEGIN\r
314 \r
315         LSC_vacio := ( l.Primero = LSC_Nulo);\r
316 \r
317 END;\r
318 \r
319 \r
320 \r
321 FUNCTION LSC_lleno( l: LSC_Lista_Simple_C): BOOLEAN;\r
322 \r
323 BEGIN\r
324 \r
325         LSC_lleno := not LSC_Almac_HayLugar( l.almac );\r
326 \r
327 END;\r
328 \r
329 \r
330 \r
331 PROCEDURE LSC_elem_cte ( l: LSC_Lista_Simple_C; VAR e: Tipo_Elem);\r
332 \r
333 var n : LSC_Nodo;\r
334 \r
335 BEGIN\r
336 \r
337    { accedo al almacenamiento por el nodo corriente }\r
338 \r
339    LSC_Almac_Acceder ( l.almac, l.Corriente, n );\r
340 \r
341 \r
342 \r
343    { y se lo asigno al parametro }\r
344 \r
345    e := n.Elem;\r
346 \r
347 END;\r
348 \r
349 \r
350 \r
351 PROCEDURE LSC_modif_cte ( VAR l: LSC_Lista_Simple_C; VAR e: Tipo_Elem);\r
352 \r
353 var n : LSC_Nodo;\r
354 \r
355 BEGIN\r
356 \r
357    { accedo al almacenamiento por el nodo corriente }\r
358 \r
359    LSC_Almac_Acceder ( l.almac, l.Corriente, n );\r
360 \r
361 \r
362 \r
363    { y la asigno al parametro }\r
364 \r
365    n.Elem := e;\r
366 \r
367 \r
368 \r
369    { y modifico el almacenamiento }\r
370 \r
371    LSC_Almac_Modificar ( l.almac, l.Corriente, n );\r
372 \r
373 \r
374 \r
375 END;\r
376 \r
377 \r
378 \r
379 PROCEDURE LSC_mover_cte ( VAR l: LSC_Lista_Simple_C; m: LSC_movimiento; VAR error: BOOLEAN );\r
380 \r
381 VAR n : LSC_Nodo; prueba: integer ;\r
382 \r
383 BEGIN\r
384 \r
385         error := FALSE;\r
386 \r
387         CASE m OF\r
388 \r
389                 LSC_primero:\r
390 \r
391                         l.Corriente := l.Primero;\r
392 \r
393                 LSC_anterior:\r
394 \r
395                   BEGIN\r
396                         { accedo al almacenamiento por el nodo corriente }\r
397 \r
398                         LSC_Almac_Acceder ( l.almac, l.Corriente, n );\r
399 \r
400 \r
401 \r
402                         {modificado, decia n.siguiente}\r
403                         IF n.ant = LSC_Nulo\r
404 \r
405 \r
406                         THEN\r
407 \r
408                             error := TRUE\r
409 \r
410                         ELSE\r
411 \r
412                                 l.corriente := n.ant;\r
413 \r
414 \r
415                   END; {BEGIN}\r
416 \r
417                 LSC_siguiente:\r
418                   BEGIN\r
419                         { accedo al almacenamiento por el nodo corriente }\r
420                              LSC_Almac_Acceder ( l.almac, l.Corriente, n );\r
421 \r
422 \r
423 \r
424                              {modificado, decia n.siguiente}\r
425                              IF n.sig = LSC_Nulo\r
426 \r
427 \r
428                              THEN\r
429 \r
430                                  error := TRUE\r
431 \r
432                              ELSE\r
433 \r
434 {decia:                         l.corriente := n.siguiente;}\r
435                                 l.corriente := n.sig;\r
436 \r
437                   END; {BEGIN}\r
438 \r
439                 {Implementacion recursiva de mover al ultimo,para listas\r
440                 doblemente enlazadas.}\r
441 \r
442                 LSC_ultimo:\r
443                   BEGIN\r
444                         { accedo al almacenamiento por el nodo corriente }\r
445 \r
446 \r
447                         LSC_mover_cte ( l, lsc_siguiente, error);\r
448 \r
449                         IF error <> true then\r
450 \r
451                             LSC_mover_cte ( l, lsc_ultimo, error);\r
452 \r
453                         error:= false\r
454 \r
455                   END; {BEGIN}\r
456 \r
457                 END;{CASE}\r
458 \r
459 END; {PROCEDURE}\r
460 \r
461 \r
462 \r
463 PROCEDURE LSC_borrar_cte ( VAR l: LSC_Lista_Simple_C );\r
464 \r
465 VAR n : LSC_Nodo;\r
466 \r
467     tmp,tmp2 : LSC_Nodo;\r
468 \r
469     tmpp : LSC_Puntero;\r
470 \r
471 BEGIN\r
472 \r
473    if l.corriente = l.primero then begin\r
474 \r
475       LSC_Almac_Acceder( l.almac, l.primero, n );\r
476 \r
477       l.primero := n.Sig;\r
478 \r
479       LSC_Almac_Liberar( l.almac, l.corriente );\r
480 \r
481       l.corriente := l.primero;\r
482 \r
483       {Asigno a l.primero^.ant un valor LSC_Nulo, en las siguientes 3 lineas}\r
484 \r
485       LSC_Almac_Acceder( l.almac, l.primero, tmp );\r
486 \r
487       tmp.ant:= LSC_Nulo;\r
488 \r
489       LSC_Almac_Modificar( l.almac, l.primero, tmp );\r
490 \r
491       end\r
492 \r
493    else begin\r
494 \r
495       tmpp := l.primero;\r
496 \r
497       LSC_Almac_Acceder( l.almac, tmpp, tmp );\r
498 \r
499       while( tmp.sig <> l.corriente ) do begin\r
500 \r
501          tmpp := tmp.sig;\r
502 \r
503          LSC_Almac_Acceder( l.almac, tmpp, tmp );\r
504 \r
505          end;\r
506 \r
507       LSC_Almac_Acceder( l.almac, l.corriente, n );\r
508 \r
509       tmp.sig := n.Sig;\r
510 \r
511       LSC_Almac_Modificar( l.almac, tmpp, tmp ); {creo que esto faltaba}\r
512 \r
513       {Agregado: este IF  modifica el anterior del siguiente, siempre\r
514       que corriente no sea el ultimo}\r
515 \r
516       IF n.sig <> LSC_Nulo THEN\r
517          BEGIN\r
518 \r
519                LSC_Almac_Acceder( l.almac, n.sig, tmp2 );\r
520 \r
521                tmp2.ant:= tmpp;\r
522 \r
523                LSC_Almac_Modificar( l.almac, tmp.sig, tmp2 );\r
524          END;\r
525 \r
526       LSC_Almac_Liberar( l.almac, l.corriente );\r
527 \r
528       l.corriente := tmpp;\r
529 \r
530       end;\r
531 \r
532 END;\r
533 \r
534 \r
535 \r
536 PROCEDURE LSC_insertar ( VAR l: LSC_Lista_Simple_C; m: LSC_movimiento; var e: Tipo_Elem );\r
537 \r
538 VAR\r
539 \r
540    p : LSC_puntero;\r
541 \r
542    n : LSC_Nodo;\r
543 \r
544    ant,sig : LSC_Nodo;\r
545 \r
546    np: LSC_Puntero;\r
547 \r
548 BEGIN\r
549 \r
550         n.ant:= lsc_nulo;\r
551 \r
552         LSC_Almac_Reservar( l.almac, np );\r
553 \r
554         n.Elem := e;\r
555 \r
556         CASE m OF\r
557 \r
558                 LSC_primero:\r
559 \r
560                 BEGIN\r
561 \r
562          {Agregado: cambiar l.primero^.ant a el nuevo nodo}\r
563          IF l.primero <> LSC_NULO THEN\r
564          BEGIN\r
565               LSC_Almac_Acceder( l.almac, l.primero, ant );\r
566 \r
567               ant.ant := np;\r
568 \r
569               LSC_Almac_Modificar( l.almac, l.primero, ant );\r
570          END;\r
571 \r
572          n.sig := l.primero;\r
573 \r
574          LSC_Almac_Modificar ( l.almac, np, n );\r
575 \r
576          l.primero := np;\r
577 \r
578                 END;\r
579 \r
580          LSC_anterior:\r
581 \r
582                 BEGIN\r
583 \r
584 \r
585          LSC_Almac_Acceder( l.almac, l.corriente, sig );\r
586 \r
587          n.sig := l.corriente;\r
588          n.ant := sig.ant;\r
589 \r
590          sig.ant := np;\r
591 \r
592 \r
593          IF n.ant <> lsc_nulo then begin\r
594 \r
595          LSC_Almac_Acceder( l.almac, n.ant, ant );\r
596 \r
597          ant.sig := np;\r
598 \r
599          LSC_Almac_Modificar( l.almac, n.ant, ant );\r
600 \r
601          end;\r
602 \r
603          LSC_Almac_Modificar( l.almac, np, n );\r
604 \r
605          LSC_Almac_Modificar( l.almac, l.corriente, sig );\r
606 \r
607          If l.corriente = L.primero then l.primero:= np;\r
608 \r
609 \r
610                 END;{BEGIN}\r
611 \r
612          LSC_siguiente:\r
613 \r
614                 BEGIN\r
615 \r
616 \r
617          LSC_Almac_Acceder( l.almac, l.corriente, ant );\r
618 \r
619          n.sig := ant.sig;\r
620          n.ant := l.corriente;\r
621 \r
622          ant.sig := np;\r
623 \r
624          {Agregado: cambia n.sig^.ant a el nuevo nodo}\r
625 \r
626          IF n.sig <> lsc_nulo then begin\r
627 \r
628          LSC_Almac_Acceder( l.almac, n.sig, sig );\r
629 \r
630          sig.ant := np;\r
631 \r
632          LSC_Almac_Modificar( l.almac, n.sig, sig );\r
633 \r
634          end;\r
635 \r
636          LSC_Almac_Modificar( l.almac, np, n );\r
637 \r
638          LSC_Almac_Modificar( l.almac, l.corriente, ant );\r
639 \r
640 \r
641 \r
642                 END;{BEGIN}\r
643                 END;{CASE}\r
644 \r
645 \r
646 \r
647         l.Corriente := np;\r
648 \r
649 \r
650 \r
651 END;\r
652 \r
653 \r
654 \r
655 PROCEDURE LSC_vaciar ( VAR l: LSC_Lista_Simple_C );\r
656 \r
657 VAR np : LSC_Puntero;\r
658 \r
659     n : LSC_Nodo;\r
660 \r
661 BEGIN\r
662 \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
665 \r
666 \r
667 (*   np := l.primero;\r
668 \r
669    while( np <> LSC_Nulo ) do begin\r
670 \r
671       LSC_Almac_Acceder( l.almac, np, n );\r
672 \r
673       LSC_Almac_Liberar( l.almac, np );\r
674 \r
675       np := n.sig;\r
676 \r
677       end;\r
678 \r
679    l.primero := LSC_Nulo;\r
680 \r
681    l.corriente := LSC_Nulo;\r
682 *)\r
683 \r
684 END;\r
685 \r
686 \r
687 \r
688 { pre: 'a' y 'b' estan creadas y 'b' esta vacia }\r
689 \r
690 { POST: 'b' tiene una copia de los elementos de 'a' y el corriente esta en el primero }\r
691 \r
692 PROCEDURE LSC_copiar ( a : LSC_Lista_Simple_C; VAR b : LSC_Lista_Simple_C );\r
693 \r
694 VAR np,mp,tmpp : LSC_Puntero;\r
695 \r
696     n,m : LSC_Nodo;\r
697 \r
698 BEGIN\r
699 \r
700 {   if a.primero = LSC_Nulo then return; {return no existe}\r
701 \r
702    if a.primero = LSC_Nulo then exit;\r
703 \r
704 \r
705    np := a.primero;\r
706 \r
707    LSC_Almac_Acceder( a.almac, np, n );\r
708 \r
709 \r
710 \r
711    LSC_Almac_Reservar( b.almac, mp );\r
712 \r
713    b.primero := mp;\r
714 \r
715    b.corriente := mp;\r
716 \r
717    m.elem := n.elem;\r
718 \r
719    m.ant := n.ant; {agregado para listas dobles}\r
720 \r
721 \r
722    while( n.sig <> LSC_Nulo ) do begin\r
723 \r
724 \r
725 \r
726       LSC_Almac_Reservar( b.almac, tmpp );\r
727 \r
728       m.sig := tmpp;\r
729 \r
730       LSC_Almac_Modificar( b.almac, mp, m );\r
731 \r
732 \r
733       np := n.sig;\r
734 \r
735       LSC_Almac_Acceder( a.almac, np, n );\r
736 \r
737 \r
738 \r
739       mp := tmpp;\r
740 \r
741       m.elem := n.elem;\r
742 \r
743       m.ant:= n.ant\r
744 \r
745 \r
746       end;\r
747 \r
748    m.sig := LSC_Nulo;\r
749 \r
750    LSC_Almac_Modificar( b.almac, mp, m );\r
751 \r
752 END;\r
753 \r
754 \r
755 \r
756 end.\r
757 \r