{$mode objfpc} unit u2listC; // кольцевые двусвязные списки 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 addLastElement(ph,p); PH:=p; end; procedure addlastelement(var PH:p2list; p:p2list); begin if ph=nil then begin ph:=p; ph^.pnext:=ph; ph^.pprev:=ph; exit; end; p^.pprev:=ph^.pprev; ph^.pprev^.pnext:=p; p^.pnext:=PH; ph^.pprev:=p; end; { procedure InsertElementBefore(var PH:p2list; var El:p2list; p:p2list); begin if ph=nil then addlastelement(ph,p) else addlastelement(El,p); end; procedure InsertElementAfter(var PH:p2list; var El:p2list; p:p2list); begin if ph=nil then InsertElementBefore(ph,el,p) else InsertElementBefore(ph,el^.pnext,p) end; } procedure InsertElementBefore(var El:p2list; p:p2list); begin addlastelement(El,p); end; procedure InsertElementAfter(var El:p2list; p:p2list); begin if ph=nil then InsertElementBefore(el,p) else InsertElementBefore(el^.pnext,p) end; // ------------------- TODO ----------------------- 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.