Einzelnen Beitrag anzeigen

Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#24

AW: Einfach verkettete Listen

  Alt 15. Mär 2011, 10:37
Ich habe mir das Tutorium von Michael Puff dieser Tage auch mal näher angesehen und daraus nachfolgende unit erstellt. Könnte mal jemand kurz drüber schauen, ob das Ganze soweit okay ist, ob ich nicht irgendwelche Speicherlecks produziere und ob man sich das inherited sparen kann, sofern es sich nur auf TObject bezieht? Danke!

Delphi-Quellcode:
unit EinfachVerketteteListen;

interface

uses
  Classes;

type
  TData = record
    Name: string;
  end;
  PNode = ^TNode;
  TNode = record
    Data: TData;
    Next: PNode;
  end;
  Tliste = class(TObject)
    function Count: integer;
    procedure clearItem(Index: integer);
    procedure AddItem(Data: TData);
    function GetItem(Index: integer): TData;
    procedure SetItem(Index: integer; Data: TData);
    procedure DelItem(Index: integer);
    procedure InsItem(Index: integer; Data: TData);
    procedure Exchange(Index1,Index2: integer);
    procedure SortByName;
    function IndexOfName (Name: string) : integer;
  private
    FirstNode, LastNode, CurrentNode: PNode;
    procedure InitList;
    procedure ClearList;
    procedure AddNode(Data: TData);
    procedure InsertNodeAfter(AfterNode: PNode; Data: TData);
    procedure DeleteNextNode(Node: PNode);
    function GetNode(Index: integer): PNode;
    Procedure Null(var Data: TData);
  public
    constructor Create;
    destructor Destroy; override;
  end;

implementation

procedure TListe.InitList;
begin
  FirstNode := nil;
  LastNode := nil;
end;

constructor TListe.Create;
begin
  inherited Create;
  InitList;
end;

procedure TListe.ClearList;
var
  Node: PNode;
begin
  CurrentNode := FirstNode;
  while (CurrentNode <> nil) do
  begin
    Node := CurrentNode.Next;
    Dispose (CurrentNode);
    CurrentNode := Node;
  end;
  InitList;
end;

destructor TListe.Destroy;
begin
  ClearList;
  inherited;
end;

procedure TListe.AddNode(Data: TData);
begin
  New(CurrentNode);
  CurrentNode.Data := Data;
  CurrentNode.Next := nil;
  if LastNode = nil then
  begin
    FirstNode := CurrentNode;
    LastNode := CurrentNode;
  end
  else
  begin
    LastNode.Next := CurrentNode;
    LastNode := CurrentNode;
  end;
end;

procedure TListe.InsertNodeAfter(AfterNode: PNode; Data: TData);
var
  Node: PNode;
begin
  New(Node);
  Node.Data := Data;
  Node.Next := AfterNode.Next;
  AfterNode.Next := Node;
end;

procedure TListe.DeleteNextNode(Node: PNode);
var
  TempNode: PNode;
begin
  if Count>1 then
  begin
    if Node.Next <> nil then
    begin
      TempNode := Node.Next;
      Node.Next := Node.Next.Next;
      Dispose(TempNode);
    end
  end
  else
    ClearList;
end;

function TListe.Count: integer;
begin
  Result := 0;
  CurrentNode := FirstNode;
  while CurrentNode <> nil do
  begin
    CurrentNode := CurrentNode.Next;
    Result := Result + 1;
  end;
end;

function TListe.GetNode(Index: integer): PNode;
var
  i: integer;
begin
  i:=0;
  CurrentNode := FirstNode;
  while ((CurrentNode <> nil) and (i < Index)) do
  begin
    i:= i+1;
    CurrentNode := CurrentNode.Next;
  end;
  Result:=CurrentNode;
end;

procedure TListe.Null(var Data: TData);
begin
  with Data do
  begin
    Name := '';
  end;
end;

procedure TListe.ClearItem(Index: integer);
var
  Node: PNode;
begin
  Node := GetNode(Index);
  Null(Node.Data);
end;

procedure TListe.AddItem(Data: TData);
begin
  AddNode(Data);
end;

function TListe.GetItem(Index: integer): TData;
var
  Node: PNode;
begin
  Null(Result);
  Node := GetNode(Index);
  Result := Node.Data;
end;

procedure TListe.SetItem(Index: integer; Data: TData);
var
  Node: PNode;
begin
  Node := GetNode(Index);
  Node.Data := Data;
end;

procedure TListe.DelItem(Index: integer);
var
  Node: PNode;
begin
  Node := GetNode(Index-1);
  DeleteNextNode(Node);
  FirstNode := GetNode(0);
  LastNode := GetNode(Count-1);
end;

procedure TListe.InsItem(Index: integer; Data: TData);
var
  Node: PNode;
begin
  Node := GetNode(Index);
  InsertNodeAfter(Node,Data);
  FirstNode := GetNode(0);
  LastNode := GetNode(Count-1);
end;

procedure TListe.Exchange(Index1,Index2: integer);
var
  Data1,Data2: TData;
begin
  Data1 := GetItem(Index1);
  Data2 := GetItem(Index2);
  SetItem(Index1,Data2);
  SetItem(Index2,Data1);
end;

procedure TListe.SortByName;
var
  i,j: integer;
begin
  for i := 0 to Count - 2 do
    for j := i+1 to Count - 1 do
      if GetItem(i).Name > GetItem(j).Name then Exchange(i,j);
end;

function TListe.IndexOfName (Name: string): integer;
var
  i: integer;
begin
  result := -1;
  for i := 0 to Count - 1 do
    if GetItem(i).Name = Name then
    begin
      result := i;
      break;
    end;
end;

end.
  Mit Zitat antworten Zitat