home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast.iso / pcmag / vol9n04.zip / LISTOBJ.PAS < prev    next >
Pascal/Delphi Source File  |  1989-10-23  |  4KB  |  167 lines

  1. UNIT ListObj;
  2. (**********************)
  3. (**)   INTERFACE    (**)
  4. (**********************)
  5.  
  6. TYPE
  7.   NodeP = ^Node;
  8.   ListP = ^List;
  9.  
  10.   Node = OBJECT {list node}
  11.     Next : NodeP;
  12.     DESTRUCTOR Done; virtual;
  13.     FUNCTION Prev : NodeP;
  14.   END;
  15.  
  16.   List = OBJECT {circular linked list}
  17.     Last : NodeP;
  18.     PROCEDURE Init;
  19.     PROCEDURE Done;
  20.     PROCEDURE Append(N : NodeP);
  21.     PROCEDURE Insert(Loc, N : NodeP);
  22.     PROCEDURE Remove(N : NodeP);
  23.     PROCEDURE SwapInList(N, M : NodeP);
  24.     FUNCTION  Empty : Boolean; 
  25.     FUNCTION  Firs : NodeP; 
  26.     FUNCTION  Next(N : NodeP) : NodeP; 
  27.     FUNCTION  Prev(N : NodeP) : NodeP; 
  28.     FUNCTION  NextCirc(N : NodeP) : NodeP; 
  29.     FUNCTION  PrevCirc(N : NodeP) : NodeP; 
  30.     FUNCTION  Nth(L : LongInt) : NodeP; 
  31.     FUNCTION  IsOnList(N : NodeP) : Boolean; 
  32.   END; 
  33.  
  34. (**********************)
  35. (**) IMPLEMENTATION (**)
  36. (**********************)
  37.  
  38. (*-methods for Node----------*)
  39.  
  40.   DESTRUCTOR Node.Done; BEGIN END;
  41.  
  42.   FUNCTION Node.Prev : NodeP; 
  43.   VAR P : NodeP; 
  44.   BEGIN
  45.     P := @Self;
  46.     WHILE P^.Next <> @Self DO P := P^.Next;
  47.     Prev := P;
  48.   END;
  49.  
  50. (*-methods for List----------*)
  51.  
  52.   PROCEDURE List.Init; 
  53.   BEGIN Last := nil; END;
  54.  
  55.   PROCEDURE List.Done; 
  56.   VAR P : NodeP; 
  57.   BEGIN
  58.     WHILE NOT Empty DO
  59.       BEGIN
  60.         P := Firs;
  61.         Remove(P);
  62.         Dispose(P, Done);
  63.       END;
  64.   END;
  65.  
  66.   PROCEDURE List.Append(N : NodeP);
  67.   {add node to end of list}
  68.   BEGIN
  69.     IF Last = NIL THEN Last := N ELSE N^.Next := Last^.Next;
  70.     Last^.Next := N; 
  71.     Last := N;
  72.   END;
  73.  
  74.   PROCEDURE List.Insert(Loc, N : NodeP);
  75.   {Insert N before Loc.  If loc = NIL, just append}
  76.   VAR P : NodeP;
  77.   BEGIN
  78.     IF (Loc = NIL) OR (last = NIL) THEN append(N)
  79.     ELSE
  80.       BEGIN
  81.         P := Last;
  82.         WHILE (P^.Next <> Loc) AND (P^.Next <> Last) DO P := P^.Next;
  83.         IF P^.Next= Loc THEN BEGIN N^.next := Loc; P^.Next := N; END;
  84.       END;
  85.   END;
  86.  
  87.   PROCEDURE List.Remove(N : NodeP);
  88.   VAR P : NodeP;
  89.   BEGIN
  90.     IF Last <> NIL THEN
  91.       BEGIN
  92.         P := Last;
  93.         WHILE (P^.Next <> N) AND (P^.Next <> Last) DO P := P^.Next;
  94.         IF P^.Next = N THEN
  95.           BEGIN
  96.             P^.Next := N^.Next;
  97.             IF Last = N THEN IF P=N THEN Last := NIL ELSE Last := P;
  98.           END;
  99.       END; 
  100.   END;
  101.  
  102.   PROCEDURE List.SwapInList(N, M : NodeP);
  103.   VAR P, Q, T : NodeP;
  104.   BEGIN
  105.     IF N = M THEN Exit;
  106.     P := N^.Prev; Q := M^.Prev;
  107.     P^.Next := M; Q^.Next := N;
  108.     T := N^.Next;
  109.     N^.Next := M^.Next;
  110.     M^.Next := T;
  111.     IF Last = M THEN Last := N
  112.     ELSE IF Last = N THEN Last := M;
  113.   END;
  114.  
  115.   FUNCTION List.Empty : Boolean; BEGIN Empty := Last = NIL; END;
  116.  
  117.   FUNCTION List.Firs : NodeP;
  118.   BEGIN
  119.     IF Last = NIL THEN Firs := NIL ELSE Firs := Last^.Next;
  120.   END;
  121.  
  122.   FUNCTION List.Next(N : NodeP) : NodeP; {non-circular}
  123.   BEGIN
  124.     IF N = Last THEN Next := NIL ELSE Next := N^.Next;
  125.   END;
  126.  
  127.   FUNCTION List.Prev(N : NodeP) : NodeP; {non-circular}
  128.   BEGIN
  129.     IF N = Firs THEN Prev := NIL ELSE Prev := N^.Prev;
  130.   END;
  131.  
  132.   FUNCTION List.NextCirc(N : NodeP) : NodeP; {circular}
  133.   BEGIN
  134.     IF last = NIL THEN NextCirc := NIL ELSE NextCirc := N^.Next;
  135.   END;
  136.  
  137.   FUNCTION List.PrevCirc(N : NodeP) : NodeP; {circular}
  138.   BEGIN
  139.     IF N = Firs THEN PrevCirc := last ELSE PrevCirc := N^.Prev;
  140.   END;
  141.  
  142.   FUNCTION List.Nth(L : LongInt) : NodeP; {circular}
  143.   VAR vL : LongInt; P : NodeP;
  144.   BEGIN
  145.     IF Last = NIL THEN Nth := NIL
  146.     ELSE
  147.       BEGIN
  148.         P := Last; vL := 0;
  149.         WHILE vL < L DO BEGIN P := P^.Next; Inc(vL); END;
  150.         Nth := P;
  151.       END;
  152.   END;
  153.  
  154.   FUNCTION List.IsOnList(N : NodeP) : boolean;
  155.   VAR P : NodeP;
  156.   BEGIN
  157.     IF Last = NIL THEN IsOnList := FALSE
  158.     ELSE
  159.       BEGIN
  160.         P := Last;
  161.         REPEAT P := P^.Next UNTIL (P = Last) OR (P = N);
  162.         IsOnList := P = N;
  163.       END;
  164.   END;
  165.  
  166. END.
  167.