babubabu

Doubly Linked List

Jan 3rd, 2014
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 6.08 KB | None | 0 0
  1. unit DoublyLinkedList;
  2.  
  3. {==============================================================================}
  4.  
  5. {$mode objfpc}{$H+}
  6.  
  7. {==============================================================================}
  8.  
  9. interface
  10.  
  11. {==============================================================================}
  12.  
  13. uses
  14.   Classes, SysUtils;
  15.  
  16. {==============================================================================}
  17.  
  18. type
  19.   TData = Cardinal;
  20.  
  21.   PElement = ^TElement;
  22.   TElement = record
  23.     Data : TData;
  24.     Next : PElement;
  25.     Prev : PElement;
  26.   end;
  27.  
  28.   TDoublyLinkedList = class
  29.     private
  30.       FFirst : PElement;
  31.       FLast  : PElement;
  32.       FCount : Cardinal;
  33.     private
  34.       procedure CreateElement(AData: TData; out AElement: PElement);
  35.       function GetElementByIndex(AIndex : Cardinal) : PElement;
  36.       function GetCapacity : Cardinal;
  37.     public
  38.       constructor Create;
  39.       destructor Destroy; override;
  40.     public
  41.       procedure Add(AElement : TData);
  42.       procedure Insert(AElement : TData; AIndex : Cardinal);
  43.       procedure Delete(AIndex : Cardinal);
  44.       procedure Clear;
  45.     public
  46.       function Get(AIndex : Cardinal) : TData;
  47.     public
  48.       procedure SaveToFile(AFileName : String);
  49.       procedure LoadFromFile(AFileName : String);
  50.       procedure Print;
  51.     public
  52.       property Count : Cardinal read fCount;
  53.       property Capacity : LongWord read GetCapacity;
  54.   end;
  55.  
  56. {------------------------------------------------------------------------------}
  57.  
  58. const
  59.   ELEMENT_DATA_SIZE = SizeOf(TData);
  60.  
  61. {==============================================================================}
  62.  
  63. implementation
  64.  
  65. {==============================================================================}
  66.  
  67. {-- TDoublyLinkedList class ---------------------------------------------------}
  68. {-- constructor/destructor ----------------------------------------------------}
  69. constructor TDoublyLinkedList.Create;
  70. begin
  71.   inherited Create;
  72.   FFirst := nil;
  73.   FLast := nil;
  74.   FCount := 0;
  75. end;
  76.  
  77. destructor TDoublyLinkedList.Destroy;
  78. begin
  79.   Clear;
  80.   Inherited Destroy;
  81. end;
  82.  
  83. {-- private -------------------------------------------------------------------}
  84.  
  85. procedure TDoublyLinkedList.CreateElement(AData: TData; out AElement: PElement);
  86. begin
  87.   New(AElement);
  88.   AElement^.Next := nil;
  89.   AElement^.Prev := nil;
  90.   AElement^.Data := AData;
  91. end;
  92.  
  93. function TDoublyLinkedList.GetElementByIndex(AIndex : Cardinal) : PElement;
  94. var
  95.   ToSearch : PElement;
  96.   tmpIndex : Word;
  97. begin
  98.   if FCount shr 1 < AIndex then
  99.   begin
  100.     ToSearch := FFirst;
  101.     while AIndex > 0 do
  102.     begin
  103.       ToSearch := ToSearch^.Next;
  104.       Dec(AIndex);
  105.     end;
  106.   end
  107.   else
  108.   begin
  109.     ToSearch := FLast;
  110.     tmpIndex := FCount - 1 - AIndex;
  111.     while tmpIndex > 0 do
  112.     begin
  113.       ToSearch := ToSearch^.Prev;
  114.       Dec(tmpIndex);
  115.     end;
  116.   end;
  117.   Result := ToSearch;
  118. end;
  119.  
  120. function TDoublyLinkedList.GetCapacity : Cardinal;
  121. begin
  122.   Result := FCount * ELEMENT_DATA_SIZE;
  123. end;
  124.  
  125. {-- public --------------------------------------------------------------------}
  126.  
  127. procedure TDoublyLinkedList.Add(AElement : TData);
  128. var
  129.   NewOne : PElement;
  130. begin
  131.   CreateElement(AElement, NewOne);
  132.  
  133.   NewOne^.Prev := FLast;
  134.   FLast := NewOne;
  135.  
  136.   if NewOne^.Prev = nil then
  137.     FFirst := NewOne
  138.   else
  139.     NewOne^.Prev^.Next := NewOne;
  140.  
  141.   Inc(FCount);
  142. end;
  143.  
  144. procedure TDoublyLinkedList.Insert(AElement : TData; AIndex : Cardinal);
  145. var
  146.   NewOne, ToSearch :  PElement;
  147. begin
  148.   if AIndex >= FCount then
  149.     Add(AElement)
  150.   else
  151.   begin
  152.     CreateElement(AElement, NewOne);
  153.  
  154.     ToSearch := GetElementByIndex(AIndex);
  155.  
  156.     NewOne^.Next := ToSearch;
  157.     If ToSearch^.Prev <> nil then
  158.     begin
  159.       NewOne^.Prev := ToSearch^.Prev;
  160.       ToSearch^.Prev^.Next := NewOne;
  161.     end
  162.     else
  163.       FFirst := NewOne;
  164.  
  165.     ToSearch^.Prev := NewOne;
  166.  
  167.     Inc(FCount);
  168.   end;
  169. end;
  170.  
  171. procedure TDoublyLinkedList.Delete(AIndex : Cardinal);
  172. var
  173.   ToDelete :  PElement;
  174. begin
  175.   if FCount <> 0 then
  176.   begin
  177.     ToDelete := GetElementByIndex(AIndex);
  178.  
  179.     if ToDelete^.Prev <> nil then
  180.       ToDelete^.Prev^.Next := ToDelete^.Next
  181.     else
  182.       FFirst := ToDelete^.Next;
  183.  
  184.     if ToDelete^.Next <> nil then
  185.       ToDelete^.Next^.Prev := ToDelete^.Prev
  186.     else
  187.       FLast := ToDelete^.Prev;
  188.  
  189.     Dispose(ToDelete);
  190.     Dec(FCount);
  191.   end;
  192. end;
  193.  
  194. procedure TDoublyLinkedList.Clear;
  195. var
  196.   ToDelete : PElement;
  197. begin
  198.   while FFirst <> nil do
  199.   begin
  200.     ToDelete := FFirst;
  201.     FFirst := FFirst^.Next;
  202.     Dispose(ToDelete);
  203.   end;
  204.   FCount := 0;
  205.   FLast := nil;
  206. end;
  207.  
  208. function TDoublyLinkedList.Get(AIndex : Cardinal) : TData;
  209. var
  210.   ToGet : PElement;
  211. begin
  212.   if AIndex >= FCount then
  213.     Result := FLast^.Data
  214.   else
  215.   begin
  216.     ToGet := GetElementByIndex(AIndex);
  217.     Result := ToGet^.Data;
  218.   end;
  219. end;
  220.  
  221. procedure TDoublyLinkedList.SaveToFile(AFileName : String);
  222. var
  223.   SaveFile : TFileStream;
  224.   ToSave   : PElement;
  225. begin
  226.   SaveFile := TFileStream.Create(AFileName, fmCreate);
  227.   ToSave := FFirst;
  228.   try
  229.     while ToSave <> nil do
  230.     begin
  231.       SaveFile.WriteBuffer(ToSave^.Data, ELEMENT_DATA_SIZE);
  232.       ToSave := ToSave^.Next;
  233.     end;
  234.   finally
  235.     FreeAndNil(SaveFile);
  236.   end;
  237. end;
  238.  
  239. procedure TDoublyLinkedList.LoadFromFile(AFileName : String);
  240. var
  241.   LoadFile : TFileStream;
  242.   ToLoad   : TData;
  243. begin
  244.   LoadFile := TFileStream.Create(AFileName, fmOpenRead);
  245.   try
  246.     while LoadFile.Position < LoadFile.Size do
  247.     begin
  248.       LoadFile.ReadBuffer(ToLoad, ELEMENT_DATA_SIZE);
  249.       Add(ToLoad);
  250.     end;
  251.   finally
  252.     FreeAndNil(LoadFile);
  253.   end;
  254. end;
  255.  
  256. procedure TDoublyLinkedList.Print;
  257. var
  258.   ToPrint : PElement;
  259.   Index   : Word;
  260. begin
  261.   ToPrint := FFirst;
  262.   Index := 0;
  263.  
  264.   Writeln('Count: ',FCount);
  265.   while ToPrint <> nil do
  266.   begin
  267.     Writeln('Index: ', Index, ' Data: ', ToPrint^.Data);
  268.     ToPrint := ToPrint^.Next;
  269.     Inc(Index);
  270.   end;
  271. end;
  272.  
  273. {-- end TDoublyLinkedList -----------------------------------------------------}
  274. {==============================================================================}
  275.  
  276. end.
Advertisement
Add Comment
Please, Sign In to add comment