{$mode objfpc} unit u2list; // использовать отдельно от ulist interface type P2list=^T2list; T2list=record key:integer; pprev:p2list; pnext:p2list; end; function createElement(key:integer):p2list; procedure addfirstelement(var PH:p2list; p:p2list); procedure addlastelement(var PH:p2list; p:p2list); procedure InsertElementBefore(var El:p2list; p:p2list); procedure InsertElementAfter(var El:p2list; p:p2list); function deleteElement(var El:p2list):p2list; procedure disposeList(var pH:p2list); function countElements(pH:p2list):integer; type TlistAction=procedure(key:integer); procedure listAction(p:p2list; proc:TListAction; backward:boolean=false); implementation function createElement(key:integer):p2list; begin new(result); result^.key:=key; result^.pnext:=nil; result^.pprev:=nil; end; procedure addfirstelement(var PH:p2list; p:p2list); begin { p^.pnext:=PH; if ph<>nil then ph^.pprev:=p; PH:=p; } if ph=nil then begin ph:=p; exit; end; p^.pnext:=PH; ph^.pprev:=p; PH:=p; end; procedure addlastelement(var PH:p2list; p:p2list); var c:p2list; begin if PH = nil then begin PH:=p; exit; end; c:=PH; while c^.pnext <>nil do c:=c^.pnext; c^.pnext:=p; p^.pprev:=c; end; procedure InsertElementBefore(var El:p2list; p:p2list); begin if (El=nil) or (El^.pprev=nil) then begin addfirstelement(el,p); exit; end; insertElementAfter(El^.pprev,p); end; procedure InsertElementAfter(var El:p2list; p:p2list); begin if El=nil then begin addfirstelement(el,p); exit; end; if El^.pnext=nil then begin addlastelement(el,p); exit; end; p^.pnext:=El^.pnext; El^.pnext:=p; p^.pprev:=El; p^.pnext^.pprev:=p; end; function deleteElement(var El:p2list):p2list; begin result:=El; if El=nil then exit; if (el^.pprev=nil)and(el^.pnext=nil) then begin // единственный элемент el:=nil; exit; end; if el^.pnext=nil then begin // последний элемент el^.pprev^.pnext:=nil; el^.pprev:=nil; exit; end; if el^.pprev=nil then begin // первый элемент el^.pnext^.pprev:=nil; el:=el^.pnext; result^.pnext:=nil; exit; end; // в середине списка el^.pprev^.pnext:=el^.pnext; el^.pnext^.pprev:=el^.pprev; el^.pprev:=nil; el^.pnext:=nil; end; procedure disposeList(var pH:p2list); begin if pH=nil then exit; disposeList(pH^.pnext); dispose(pH); pH:=nil; end; function countElements(pH:plist):integer; var c:plist; begin c:=pH; result:=0; while c <>nil do begin c:=c^.pnext; inc(result); end; end; procedure listAction(p:p2list; proc:TListAction; backward:boolean=false); var c:p2list; begin c:=p; while c<>nil do begin proc(c^.key); if backward then c:=c^.pprev else c:=c^.pnext; end; end; end.