home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 December
/
simtel1292_SIMTEL_1292_Walnut_Creek.iso
/
msdos
/
pcmag
/
vol9n04.arc
/
LISTOBJ.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1989-10-23
|
4KB
|
167 lines
UNIT ListObj;
(**********************)
(**) INTERFACE (**)
(**********************)
TYPE
NodeP = ^Node;
ListP = ^List;
Node = OBJECT {list node}
Next : NodeP;
DESTRUCTOR Done; virtual;
FUNCTION Prev : NodeP;
END;
List = OBJECT {circular linked list}
Last : NodeP;
PROCEDURE Init;
PROCEDURE Done;
PROCEDURE Append(N : NodeP);
PROCEDURE Insert(Loc, N : NodeP);
PROCEDURE Remove(N : NodeP);
PROCEDURE SwapInList(N, M : NodeP);
FUNCTION Empty : Boolean;
FUNCTION Firs : NodeP;
FUNCTION Next(N : NodeP) : NodeP;
FUNCTION Prev(N : NodeP) : NodeP;
FUNCTION NextCirc(N : NodeP) : NodeP;
FUNCTION PrevCirc(N : NodeP) : NodeP;
FUNCTION Nth(L : LongInt) : NodeP;
FUNCTION IsOnList(N : NodeP) : Boolean;
END;
(**********************)
(**) IMPLEMENTATION (**)
(**********************)
(*-methods for Node----------*)
DESTRUCTOR Node.Done; BEGIN END;
FUNCTION Node.Prev : NodeP;
VAR P : NodeP;
BEGIN
P := @Self;
WHILE P^.Next <> @Self DO P := P^.Next;
Prev := P;
END;
(*-methods for List----------*)
PROCEDURE List.Init;
BEGIN Last := nil; END;
PROCEDURE List.Done;
VAR P : NodeP;
BEGIN
WHILE NOT Empty DO
BEGIN
P := Firs;
Remove(P);
Dispose(P, Done);
END;
END;
PROCEDURE List.Append(N : NodeP);
{add node to end of list}
BEGIN
IF Last = NIL THEN Last := N ELSE N^.Next := Last^.Next;
Last^.Next := N;
Last := N;
END;
PROCEDURE List.Insert(Loc, N : NodeP);
{Insert N before Loc. If loc = NIL, just append}
VAR P : NodeP;
BEGIN
IF (Loc = NIL) OR (last = NIL) THEN append(N)
ELSE
BEGIN
P := Last;
WHILE (P^.Next <> Loc) AND (P^.Next <> Last) DO P := P^.Next;
IF P^.Next= Loc THEN BEGIN N^.next := Loc; P^.Next := N; END;
END;
END;
PROCEDURE List.Remove(N : NodeP);
VAR P : NodeP;
BEGIN
IF Last <> NIL THEN
BEGIN
P := Last;
WHILE (P^.Next <> N) AND (P^.Next <> Last) DO P := P^.Next;
IF P^.Next = N THEN
BEGIN
P^.Next := N^.Next;
IF Last = N THEN IF P=N THEN Last := NIL ELSE Last := P;
END;
END;
END;
PROCEDURE List.SwapInList(N, M : NodeP);
VAR P, Q, T : NodeP;
BEGIN
IF N = M THEN Exit;
P := N^.Prev; Q := M^.Prev;
P^.Next := M; Q^.Next := N;
T := N^.Next;
N^.Next := M^.Next;
M^.Next := T;
IF Last = M THEN Last := N
ELSE IF Last = N THEN Last := M;
END;
FUNCTION List.Empty : Boolean; BEGIN Empty := Last = NIL; END;
FUNCTION List.Firs : NodeP;
BEGIN
IF Last = NIL THEN Firs := NIL ELSE Firs := Last^.Next;
END;
FUNCTION List.Next(N : NodeP) : NodeP; {non-circular}
BEGIN
IF N = Last THEN Next := NIL ELSE Next := N^.Next;
END;
FUNCTION List.Prev(N : NodeP) : NodeP; {non-circular}
BEGIN
IF N = Firs THEN Prev := NIL ELSE Prev := N^.Prev;
END;
FUNCTION List.NextCirc(N : NodeP) : NodeP; {circular}
BEGIN
IF last = NIL THEN NextCirc := NIL ELSE NextCirc := N^.Next;
END;
FUNCTION List.PrevCirc(N : NodeP) : NodeP; {circular}
BEGIN
IF N = Firs THEN PrevCirc := last ELSE PrevCirc := N^.Prev;
END;
FUNCTION List.Nth(L : LongInt) : NodeP; {circular}
VAR vL : LongInt; P : NodeP;
BEGIN
IF Last = NIL THEN Nth := NIL
ELSE
BEGIN
P := Last; vL := 0;
WHILE vL < L DO BEGIN P := P^.Next; Inc(vL); END;
Nth := P;
END;
END;
FUNCTION List.IsOnList(N : NodeP) : boolean;
VAR P : NodeP;
BEGIN
IF Last = NIL THEN IsOnList := FALSE
ELSE
BEGIN
P := Last;
REPEAT P := P^.Next UNTIL (P = Last) OR (P = N);
IsOnList := P = N;
END;
END;
END.