home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / spezial / 22 / lists / lists1.pas
Encoding:
Pascal/Delphi Source File  |  1991-01-04  |  13.2 KB  |  478 lines

  1. (* ----------------------------------------------------- *)
  2. (*                      LISTS.PAS                        *)
  3. (*                                                       *)
  4. (* ■ SListNodePtr: Knotenobjekt für einfach verkettete   *)
  5. (*   Liste...                                            *)
  6. (* ■ DListNodePtr: und für doppelt verkettete Liste.     *)
  7. (* ■ AbstractList: Abstraktes Objekt, als Grundlage für  *)
  8. (*   Listen verwaltenden Objekt.                         *)
  9. (* ■ DListCollection: Implementiert Verwaltung für       *)
  10. (*   doppelt verkettete, unsortierte Liste. Die vielen   *)
  11. (*   Methoden sollen den Umgang erleichern.              *)
  12. (*                                                       *)
  13. (*          (c) 1991 by R.Reichert & toolbox             *)
  14. (* ----------------------------------------------------- *)
  15. UNIT Lists;
  16.  
  17. INTERFACE
  18.  
  19. USES UBase;
  20.  
  21. CONST
  22.   DLOk    = 0;
  23.   DLNoMem = 1; { ReturnCode, falls es zuwenig Speicher hat}
  24.  
  25. TYPE
  26.   SListNodePtr = ^SListNode;
  27.   SListNode = OBJECT (Base)
  28.     Next : SListNodePtr;
  29.     Data : BasePtr;
  30.  
  31.     CONSTRUCTOR Init;
  32.     CONSTRUCTOR InitSet (N : SListNodePtr;
  33.                          D : BasePtr);
  34.     PROCEDURE SetNext (N : SListNodePtr);
  35.     PROCEDURE SetData (D : BasePtr);
  36.     FUNCTION GetNextNode : SListNodePtr;
  37.     FUNCTION GetData : BasePtr;
  38.     DESTRUCTOR Done;                               VIRTUAL;
  39.   END;
  40.  
  41.   DListNodePtr = ^DListNode;
  42.   DListNode = OBJECT (SListNode)
  43.     Prev : DListNodePtr;
  44.  
  45.     CONSTRUCTOR Init;
  46.     CONSTRUCTOR InitSet (P, N : DListNodePtr;
  47.                          D : BasePtr);
  48.     PROCEDURE SetNext (N : DListNodePtr);
  49.     PROCEDURE SetPrev (P : DListNodePtr);
  50.     FUNCTION GetPrev : DListNodePtr;
  51.     FUNCTION GetNext : DListNodePtr;
  52.   END;
  53.  
  54.   AbstractListPtr = ^AbstractList;
  55.   AbstractList = OBJECT (Base)
  56.     CONSTRUCTOR Init;
  57.     PROCEDURE Put (D : BasePtr);                   VIRTUAL;
  58.     PROCEDURE Insert (D : BasePtr);                VIRTUAL;
  59.     PROCEDURE Delete;                              VIRTUAL;
  60.     PROCEDURE Clear;                               VIRTUAL;
  61.     FUNCTION GetActData : BasePtr;                 VIRTUAL;
  62.     FUNCTION GetNumber : LONGINT;                  VIRTUAL;
  63.     DESTRUCTOR Done;                               VIRTUAL;
  64.   END;
  65.  
  66.   DListCollectionPtr = ^DListCollection;
  67.   DListCollection = OBJECT (AbstractList)
  68.  
  69.     FreeHeap,
  70.     Counter : LONGINT;
  71.     OverFlow: BOOLEAN;
  72.     First, Last,
  73.     Act,
  74.     Left, Right : DListNodePtr;
  75.     ReturnCode  : BYTE;
  76.  
  77.     CONSTRUCTOR Init;
  78.     PROCEDURE SetFreeHeap (FrH : LONGINT);         VIRTUAL;
  79.     PROCEDURE SetOverFlow (O : BOOLEAN);           VIRTUAL;
  80.     PROCEDURE Put (D : BasePtr);                   VIRTUAL;
  81.     PROCEDURE Insert (D : BasePtr);                VIRTUAL;
  82.     PROCEDURE Delete;                              VIRTUAL;
  83.     PROCEDURE Clear;                               VIRTUAL;
  84.     PROCEDURE SetActNode (N : DListNodePtr);       VIRTUAL;
  85.     PROCEDURE SetActNodeTo (Nr : LONGINT);         VIRTUAL;
  86.  
  87.     FUNCTION GetNumber : LONGINT;                  VIRTUAL;
  88.     FUNCTION GetFreeHeap : LONGINT;                VIRTUAL;
  89.     FUNCTION GetOverFlow : BOOLEAN;                VIRTUAL;
  90.     FUNCTION GetReturnCode : BYTE;                 VIRTUAL;
  91.     { Die folgenden ...Node-Methoden geben einen Zeiger
  92.       auf den Knoten, die ...Data-Methoden auf das Daten-
  93.       objekt dieser Methoden.                             }
  94.     FUNCTION GetActNode : DListNodePtr;            VIRTUAL;
  95.     FUNCTION GetActData : BasePtr;                 VIRTUAL;
  96.     FUNCTION GetNextNode : DListNodePtr;           VIRTUAL;
  97.     FUNCTION GetNextData : BasePtr;                VIRTUAL;
  98.     FUNCTION GetPrevNode : DListNodePtr;           VIRTUAL;
  99.     FUNCTION GetPrevData : BasePtr;                VIRTUAL;
  100.     FUNCTION GetFirstNode: DListNodePtr;           VIRTUAL;
  101.     FUNCTION GetFirstData: BasePtr;                VIRTUAL;
  102.     { GetLast... beziehen sich nicht auf den Knoten Last,
  103.       der nie Daten enthält, sondern auf den letzten
  104.       Knoten, der noch Daten enthält, also auf den
  105.       Vorgänger von Last.                                 }
  106.     FUNCTION GetLastNode : DListNodePtr;           VIRTUAL;
  107.     FUNCTION GetLastData : BasePtr;                VIRTUAL;
  108.     { Die folgenden Methoden verschieben den Knotenzeiger
  109.       Act zum nächsten,vorhergehenden, ersten oder letzten
  110.       Knoten und einen Zeiger auf dessen Datenobjekt
  111.       zurück.                                             }
  112.     FUNCTION GotoNextData: BasePtr;                VIRTUAL;
  113.     FUNCTION GotoPrevData: BasePtr;                VIRTUAL;
  114.     FUNCTION GotoFirstData: BasePtr;               VIRTUAL;
  115.     FUNCTION GotoLastData: BasePtr;                VIRTUAL;
  116.     { IsOnLast ist TRUE, wenn Act^.Data auf das letzte
  117.       Datenobjekt zeigt (dh, Act^.Next=Last ist).         }
  118.     FUNCTION IsOnLast : BOOLEAN;                   VIRTUAL;
  119.     DESTRUCTOR Done;                               VIRTUAL;
  120.   END;
  121.  
  122. IMPLEMENTATION
  123.  
  124. (* ───────────────────────────────────────────────────── *)
  125. (*            Implementation von SListNode               *)
  126. (* ───────────────────────────────────────────────────── *)
  127. CONSTRUCTOR SListNode.Init;
  128. BEGIN
  129.   Next := NIL;  Data := NIL
  130. END;
  131.  
  132. CONSTRUCTOR SListNode.InitSet (N:SListNodePtr; D:BasePtr);
  133. BEGIN
  134.   Next := N;    Data := D
  135. END;
  136.  
  137. PROCEDURE SListNode.SetNext (N : SListNodePtr);
  138. BEGIN
  139.   Next := N
  140. END;
  141.  
  142. PROCEDURE SListNode.SetData (D : BasePtr);
  143. BEGIN
  144.   Data := D
  145. END;
  146.  
  147. FUNCTION SListNode.GetNextNode : SListNodePtr;
  148. BEGIN
  149.   GetNextNode := Next
  150. END;
  151.  
  152. FUNCTION SListNode.GetData : BasePtr;
  153. BEGIN
  154.   GetData := Data
  155. END;
  156.  
  157. DESTRUCTOR SListNode.Done;
  158. BEGIN
  159.   IF Data<>NIL THEN
  160.     Dispose (Data, Done)
  161. END;
  162.  
  163. (* ───────────────────────────────────────────────────── *)
  164. (*              Implementation von DListNode             *)
  165. (* ───────────────────────────────────────────────────── *)
  166. CONSTRUCTOR DListNode.Init;
  167. BEGIN
  168.   SListNode.Init;   Prev := NIL;
  169. END;
  170.  
  171. CONSTRUCTOR DListNode.InitSet (P,N:DListNodePtr;D:BasePtr);
  172. BEGIN
  173.   Next := N;  Prev := P;  Data := D
  174. END;
  175.  
  176. PROCEDURE DListNode.SetNext (N : DListNodePtr);
  177. BEGIN
  178.   Next := N
  179. END;
  180.  
  181. PROCEDURE DListNode.SetPrev (P : DListNodePtr);
  182. BEGIN
  183.   Prev := P
  184. END;
  185.  
  186. FUNCTION DListNode.GetPrev : DListNodePtr;
  187. BEGIN
  188.   GetPrev := Prev
  189. END;
  190.  
  191. FUNCTION DListNode.GetNext : DListNodePtr;
  192. BEGIN
  193.   GetNext := DListNodePtr (Next)
  194. END;
  195.  
  196. (* ───────────────────────────────────────────────────── *)
  197. (*       (Nicht-) Implementation von AbstractList        *)
  198. (* ───────────────────────────────────────────────────── *)
  199. CONSTRUCTOR AbstractList.Init;
  200. BEGIN  Abstract ('AbstractList');  END;
  201.  
  202. PROCEDURE AbstractList.Put (D : BasePtr);
  203. BEGIN  Abstract ('AbstractList');  END;
  204.  
  205. PROCEDURE AbstractList.Insert (D : BasePtr);
  206. BEGIN  Abstract ('AbstractList');  END;
  207.  
  208. PROCEDURE AbstractList.Delete;
  209. BEGIN  Abstract ('AbstractList');  END;
  210.  
  211. PROCEDURE AbstractList.Clear;
  212. BEGIN  Abstract ('AbstractList');  END;
  213.  
  214. FUNCTION AbstractList.GetActData : BasePtr;
  215. BEGIN  Abstract ('AbstractList');  END;
  216.  
  217. FUNCTION AbstractList.GetNumber : LONGINT;
  218. BEGIN  Abstract ('AbstractList');  END;
  219.  
  220. DESTRUCTOR AbstractList.Done;
  221. BEGIN  Abstract ('AbstractList');  END;
  222.  
  223. (* ───────────────────────────────────────────────────── *)
  224. (*           Implementation von DListCollection          *)
  225. (* ───────────────────────────────────────────────────── *)
  226. CONSTRUCTOR DListCollection.Init;
  227. BEGIN
  228.   Counter := 0;    FreeHeap := 0;     OverFlow := TRUE;
  229.   First   := NIL;  Last     := NIL;   Act      := NIL;
  230.   Left    := NIL;  Right    := NIL;   ReturnCode := DLOk;
  231. END;
  232.  
  233. PROCEDURE DListCollection.SetFreeHeap (FrH : LONGINT);
  234. BEGIN
  235.   FreeHeap := FrH;
  236.   IF FreeHeap>MemAvail THEN FreeHeap := MemAvail;
  237. END;
  238.  
  239. PROCEDURE DListCollection.SetOverFlow (O : BOOLEAN);
  240. BEGIN
  241.   OverFlow := O;
  242. END;
  243.  
  244. PROCEDURE DListCollection.Put (D : BasePtr);
  245.   VAR p : DListNodePtr;
  246. BEGIN
  247.   IF D<>NIL THEN BEGIN
  248.     IF FreeHeap+SizeOf (D^) > MemAvail THEN BEGIN
  249.       Dispose (D);
  250.       ReturnCode := DLNoMem
  251.     END ELSE IF First=Last THEN BEGIN
  252.       Last := New (DListNodePtr, Init);
  253.       First:= New (DListNodePtr, InitSet (NIL, Last, D));
  254.       Last^.SetNext (NIL);
  255.       Last^.SetPrev (First);
  256.       Act := First;
  257.       Inc (Counter);
  258.     END ELSE BEGIN
  259.       Left := Act;
  260.       Right:= Act^.GetNext;
  261.       p := New (DListNodePtr, InitSet (Left, Right, D));
  262.       Left^.SetNext (p);
  263.       Right^.SetPrev (p);
  264.       Act := p;
  265.       Inc (Counter);
  266.     END
  267.   END ELSE
  268.     ReturnCode := DLNoMem;
  269. END;
  270.  
  271. PROCEDURE DListCollection.Insert (D : BasePtr);
  272. BEGIN
  273.   Put (D);
  274. END;
  275.  
  276. PROCEDURE DListCollection.Delete;
  277.   VAR p : DListNodePtr;
  278. BEGIN
  279.   IF First^.GetNext=Last THEN BEGIN
  280.     Dispose (First, Done);         { First ist gleich Act }
  281.     First := NIL;  Last := NIL;       { Liste wieder leer }
  282.     Act   := NIL;  Left := NIL; Right := NIL;
  283.     Dec (Counter);
  284.   END ELSE                      { sonst, wenn Liste nicht }
  285.   IF NOT (First = Last) THEN BEGIN      { leer, entfernen }
  286.     Left := Act^.GetPrev;
  287.     Right:= Act^.GetNext;
  288.     Left^.SetNext (Right);
  289.     Right^.SetPrev (Left);
  290.     p := Act;
  291.     IF NOT (Act^.GetNext = Last) THEN
  292.       Act := Right
  293.     ELSE
  294.       Act := Left;
  295.     Dispose (p, Done);
  296.     Dec (Counter);
  297.   END;
  298. END;
  299.  
  300. PROCEDURE DListCollection.Clear;
  301.   VAR p : DListNodePtr;
  302. BEGIN
  303.   IF NOT (First = Last) THEN BEGIN     { Wenn Liste nicht }
  304.     Act := First;                            { leer, dann }
  305.     WHILE (Act<>NIL) DO BEGIN               { durchlaufen }
  306.       p := Act^.GetNext;
  307.       Dispose (Act, Done);                  { und löschen }
  308.       Act := p;
  309.     END;
  310.     First := NIL;  Last := NIL;  Act := NIL;
  311.     Right := NIL;  Left := NIL;
  312.   END;
  313. END;
  314.  
  315. PROCEDURE DListCollection.SetActNode (N : DListNodePtr);
  316. BEGIN
  317.   IF N<>NIL THEN Act := N;
  318. END;
  319.  
  320. PROCEDURE DListCollection.SetActNodeTo (Nr : LONGINT);
  321.   VAR i : LONGINT;
  322. BEGIN
  323.   IF First<>NIL THEN BEGIN
  324.     Act := First; i := 1;
  325.     WHILE (i<Counter) AND (i<Nr) DO BEGIN
  326.       Act := Act^.GetNext;  Inc (i);
  327.     END;
  328.   END;
  329. END;
  330.  
  331. FUNCTION DListCollection.GetNumber : LONGINT;
  332. BEGIN
  333.   GetNumber := Counter;
  334. END;
  335.  
  336. FUNCTION DListCollection.GetFreeHeap : LONGINT;
  337. BEGIN
  338.   GetFreeHeap := FreeHeap;
  339. END;
  340.  
  341. FUNCTION DListCollection.GetOverFlow : BOOLEAN;
  342. BEGIN
  343.   GetOverFlow := OverFlow;
  344. END;
  345.  
  346. FUNCTION DListCollection.GetReturnCode : BYTE;
  347. BEGIN
  348.   GetReturnCode := ReturnCode;  ReturnCode := DLOk;
  349. END;
  350.  
  351. FUNCTION DListCollection.GetActNode : DListNodePtr;
  352. BEGIN
  353.   GetActNode := Act;
  354. END;
  355.  
  356. FUNCTION DListCollection.GetActData : BasePtr;
  357. BEGIN
  358.   GetActData := Act^.GetData;
  359. END;
  360.  
  361. FUNCTION DListCollection.GetNextNode : DListNodePtr;
  362. BEGIN
  363.   GetNextNode := Act^.GetNext;
  364. END;
  365.  
  366. FUNCTION DListCollection.GetNextData : BasePtr;
  367. BEGIN
  368.   IF Act^.GetNext<>Last THEN
  369.     GetNextData := Act^.GetNext^.GetData
  370.   ELSE
  371.     GetNextData := NIL;
  372. END;
  373.  
  374. FUNCTION DListCollection.GetPrevNode : DListNodePtr;
  375. BEGIN
  376.   GetPrevNode := Act^.GetPrev;
  377. END;
  378.  
  379. FUNCTION DListCollection.GetPrevData : BasePtr;
  380. BEGIN
  381.   IF Act^.GetPrev<>NIL THEN
  382.     GetPrevData := Act^.GetPrev^.GetData
  383.   ELSE
  384.     GetPrevData := NIL;
  385. END;
  386.  
  387. FUNCTION DListCollection.GetFirstNode: DListNodePtr;
  388. BEGIN
  389.   GetFirstNode := First;
  390. END;
  391.  
  392. FUNCTION DListCollection.GetFirstData: BasePtr;
  393. BEGIN
  394.   IF First<>NIL THEN GetFirstData := First^.GetData
  395.                 ELSE GetFirstData := NIL;
  396. END;
  397.  
  398. FUNCTION DListCollection.GetLastNode : DListNodePtr;
  399. BEGIN
  400.   IF Last<>NIL THEN GetLastNode := Last^.GetPrev
  401.                ELSE GetLastNode := NIL;
  402. END;
  403.  
  404. FUNCTION DListCollection.GetLastData : BasePtr;
  405. BEGIN
  406.   IF Last<>NIL THEN
  407.     GetLastData := Last^.GetPrev^.GetData
  408.   ELSE
  409.     GetLastData := NIL;
  410. END;
  411.  
  412. FUNCTION DListCollection.GotoNextData: BasePtr;
  413. BEGIN
  414.   IF NOT (First = Last) THEN BEGIN
  415.     IF NOT (Act^.GetNext = Last) THEN BEGIN
  416.       Act := Act^.GetNext;
  417.       GotoNextData := Act^.GetData;
  418.     END ELSE
  419.       IF NOT OverFlow THEN
  420.         GotoNextData := NIL
  421.       ELSE BEGIN
  422.         Act := First;
  423.         GotoNextData := Act^.GetData;
  424.       END
  425.   END ELSE
  426.     GotoNextData := NIL;
  427. END;
  428.  
  429. FUNCTION DListCollection.GotoPrevData: BasePtr;
  430. BEGIN
  431.   IF NOT (First = Last) THEN BEGIN
  432.     IF NOT (Act^.GetPrev = NIL) THEN BEGIN
  433.       Act := Act^.GetPrev;
  434.       GotoPrevData := Act^.GetData;
  435.     END ELSE
  436.       IF NOT OverFlow THEN
  437.         GotoPrevData := NIL
  438.       ELSE BEGIN
  439.         Act := Last^.GetPrev;
  440.         GotoPrevData := Act^.GetData;
  441.       END
  442.   END ELSE
  443.     GotoPrevData := NIL;
  444. END;
  445.  
  446. FUNCTION DListCollection.GotoFirstData: BasePtr;
  447. BEGIN
  448.   IF NOT (First = Last) THEN BEGIN
  449.     Act := First;
  450.     GotoFirstData := Act^.GetData;
  451.   END ELSE
  452.     GotoFirstData := NIL;
  453. END;
  454.  
  455. FUNCTION DListCollection.GotoLastData: BasePtr;
  456. BEGIN
  457.   IF NOT (First = Last) THEN BEGIN
  458.     Act := Last;
  459.     GotoLastData := Act^.GetData;
  460.   END ELSE
  461.     GotoLastData := NIL;
  462. END;
  463.  
  464. FUNCTION DListCollection.IsOnLast : BOOLEAN;
  465. BEGIN
  466.   IsOnLast := (Act^.GetNext=Last);
  467. END;
  468.  
  469. DESTRUCTOR DListCollection.Done;
  470. BEGIN
  471.   Clear;
  472. END;
  473.  
  474. END.
  475. (* ----------------------------------------------------- *)
  476. (*                  Ende von LISTS.PAS                   *)
  477. (* ----------------------------------------------------- *)
  478.