home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / OB3.2D2.DMS / in.adf / Module / linkedlists.mod < prev    next >
Encoding:
Text File  |  1994-08-05  |  4.6 KB  |  204 lines

  1. (*-------------------------------------------------------------------------*)
  2. (*                                                                         *)
  3. (*  Amiga Oberon Library Module: LinkedList           Date: 02-Nov-92      *)
  4. (*                                                                         *)
  5. (*   © 1992 by Fridtjof Siebert                                            *)
  6. (*                                                                         *)
  7. (*-------------------------------------------------------------------------*)
  8.  
  9. MODULE LinkedLists;
  10.  
  11. IMPORT
  12. (* $IFNOT NoCheck *)
  13.        Requests,
  14. (* $END *)
  15.        BT * := BasicTypes;
  16.  
  17.  
  18. TYPE
  19.   Node * = POINTER TO NodeDesc;
  20.   List * = POINTER TO ListDesc;
  21.  
  22.   NodeDesc * = RECORD (BT.ANYDesc)
  23.     next-,prev-: Node;
  24.     list: List;
  25.   END;
  26.  
  27.   ListDesc* = RECORD (BT.COLLECTIONDesc);
  28.     head-: Node;
  29.     tail-: Node;
  30.     remallowed: INTEGER;
  31.     numElements: LONGINT;
  32.   END;
  33.  
  34.  
  35. PROCEDURE Create * (): List;
  36. VAR
  37.   list: List;
  38. BEGIN
  39.   NEW(list);
  40.   RETURN list;
  41. END Create;
  42.  
  43.  
  44. PROCEDURE (list: List) Init*;
  45. BEGIN
  46.   list.head := NIL;
  47.   list.tail := NIL;
  48.   list.remallowed := 0;
  49.   list.numElements := 0;
  50. END Init;
  51.  
  52.  
  53. PROCEDURE (list: List) AddHead*(n: Node);
  54. BEGIN
  55. (* $IFNOT NoCheck THEN *)
  56.   IF n.list#NIL THEN Requests.Fail("LinkedLists: Element added to two lists!") END;
  57. (* $END *)
  58.   n.list := list;
  59.   n.next := list.head;
  60.   n.prev := NIL;
  61.   IF n.next=NIL THEN list.tail   := n;
  62.                 ELSE n.next.prev := n END;
  63.   list.head := n;
  64.   INC(list.numElements);
  65. END AddHead;
  66.  
  67.  
  68. PROCEDURE (list: List) AddTail*(n: Node);
  69. BEGIN
  70. (* $IFNOT NoCheck THEN *)
  71.   IF n.list#NIL THEN Requests.Fail("LinkedLists: Element added to two lists!") END;
  72. (* $END *)
  73.   n.list := list;
  74.   n.prev := list.tail;
  75.   n.next := NIL;
  76.   IF n.prev=NIL THEN list.head   := n;
  77.                 ELSE n.prev.next := n END;
  78.   list.tail := n;
  79.   INC(list.numElements);
  80. END AddTail;
  81.  
  82.  
  83. PROCEDURE (n: Node) Remove*;
  84. BEGIN
  85. (* $IFNOT NoCheck THEN *)
  86.   IF (n.list=NIL) THEN Requests.Fail("LinkedLists: Remove called with Element not added to a list!") END;
  87.   IF (n.list.remallowed#0) THEN Requests.Fail("LinkedLists: Remove called within Do or DoBackward") END;
  88. (* $END *)
  89.   IF n.next#NIL THEN n.next.prev := n.prev ELSE n.list.tail := n.prev END;
  90.   IF n.prev#NIL THEN n.prev.next := n.next ELSE n.list.head := n.next END;
  91.   DEC(n.list.numElements);
  92.   n.list := NIL;
  93. END Remove;
  94.  
  95.  
  96. PROCEDURE (list: List) RemHead*(): Node;
  97. VAR n: Node;
  98. BEGIN
  99.   n := list.head;
  100.   IF n#NIL THEN n.Remove END; 
  101.   RETURN n;
  102. END RemHead;
  103.  
  104.  
  105. PROCEDURE (list: List) RemTail*(): Node;
  106. VAR n: Node;
  107. BEGIN
  108.   n := list.tail;
  109.   IF n#NIL THEN n.Remove END;
  110.   RETURN n;
  111. END RemTail;
  112.  
  113.  
  114. PROCEDURE (x: Node) AddBefore*(n: Node);
  115. (* fügt n vor x in die Liste ein *)
  116.  
  117. BEGIN
  118. (* $IFNOT NoCheck THEN *)
  119.   IF x.list=NIL THEN Requests.Fail("LinkedLists: AddBefore() called with Element not added to a list!") END;
  120.   IF n.list#NIL THEN Requests.Fail("LinkedLists: Element added to two lists!") END;
  121. (* $END *)
  122.   n.prev := x.prev;
  123.   n.next := x;
  124.   x.prev := n;
  125.   IF n.prev=NIL THEN x.list.head := n
  126.                 ELSE n.prev.next := n END;
  127.   INC(x.list.numElements);
  128.   n.list := x.list;
  129. END AddBefore;
  130.  
  131.  
  132. PROCEDURE (x: Node) AddBehind*(n: Node);
  133. (* fügt n hinter x in die Liste ein *)
  134.  
  135. BEGIN
  136. (* $IFNOT NoCheck THEN *)
  137.   IF x.list=NIL THEN Requests.Fail("LinkedLists: AddBehind() called with Element not added to a list!") END;
  138.   IF n.list#NIL THEN Requests.Fail("LinkedLists: Element added to two lists!") END;
  139. (* $END *)
  140.   n.next := x.next;
  141.   n.prev := x;
  142.   x.next := n;
  143.   IF n.next=NIL THEN x.list.tail := n
  144.                 ELSE n.next.prev := n END;
  145.   INC(x.list.numElements);
  146.   n.list := x.list;
  147. END AddBehind;
  148.  
  149.  
  150. PROCEDURE (list: List) Add * (x: BT.ANY);  
  151. (* add x to c.
  152.  * depending on the implementation it is added at some point to the
  153.  * collection.
  154.  *)
  155.  
  156. BEGIN
  157.   list.AddTail(x(Node));
  158. END Add;
  159.  
  160.  
  161. PROCEDURE (list: List) Remove * (x: BT.ANY);
  162. (* removes x from c.
  163.  *)
  164.  
  165. BEGIN
  166.   x(Node).Remove;
  167. END Remove;
  168.  
  169.  
  170. PROCEDURE (list: List) nbElements * (): LONGINT;
  171. (* returns the number of elements within c.
  172.  *)
  173. BEGIN
  174.   RETURN list.numElements;
  175. END nbElements;
  176.  
  177.  
  178. PROCEDURE (list: List) Do * (p: BT.DoProc; par: BT.ANY);
  179. (* calls p(x,par) for every element x stored within c.
  180.  * par passes some additional information to p. par is not touched by Do.
  181.  *)
  182.  
  183. VAR n: Node;
  184. BEGIN
  185.   INC(list.remallowed);
  186.   n := list.head; WHILE n#NIL DO p(n,par); n := n.next END;
  187.   DEC(list.remallowed);
  188. END Do;
  189.  
  190.  
  191. PROCEDURE (list: List) DoBackward*(p: BT.DoProc; par: BT.ANY);
  192. VAR n: Node;
  193. BEGIN
  194.   INC(list.remallowed);
  195.   n := list.tail; WHILE n#NIL DO p(n,par); n := n.prev END;
  196.   DEC(list.remallowed);
  197. END DoBackward;
  198.  
  199.  
  200. END LinkedLists.
  201.  
  202.  
  203.  
  204.