![]() |
Re: Einfach verkettete Listen
Ich bin da nicht ganz zufrieden:
Delphi-Quellcode:
Wenn es den FirstNode und den LastNode gibt sollte mann sie auch nutzen, wobei bei den einfach verketteten Listen der LastNode eigentlich überflüssig ist.
procedure ClearList;
var TempNode: PNode; begin CurrentNode := FirstNode; while (CurrentNode <> nil) do begin TempNode := CurrentNode.Next; Dispose (CurrentNode); CurrentNode := TempNode; end; FirstNode := nil; LastNode := nil; end;
Delphi-Quellcode:
Mir gefällt hier "Return until" besser, weil es mir logischer erscheint.
procedure ClearList;
// ---- TempNode ist überflüssig //var // TempNode: PNode; begin CurrentNode := FirstNode; repeat FirstNode:=FirstNode^.Next; // FirstNode zeigt immer auf den ersten gültigen... dispose(CurrentNode); // Freigeben CurrentNode:=FirstNode; // CurrentNode nachziehen until CurrentNode=Nil; //FirstNode := nil; ----das ist er schon!! LastNode := FirstNode; end; Edit: einfügen von Daten an beliebiger Stelle in eine doppelt verkettete Liste:
Delphi-Quellcode:
{ FirstNode ist wirklich der erste! } { CurrentNode enthält Daten und .next und .last sind mit Nil vorbelegt! } begin LastNode:=FirstNode; While (LastNode.next<>Nil) and (LastNode^.data<>MeineBedingung) do LastNode:=LastNode^.next; {-- vor LastNode einfügen --} CurrentNode^.last:=LastNode^.last; CurrentNode^.last^.next:=CurrentNode; CurrentNode^.next:=LastNode; LastNode^.last:=CurrentNode; {-- nach LastNode einfügen --} CurrentNode^.last:=LastNode; CurentNode^.next:=LastNode^.next; LastNode^.next:=CurrentNode; if CurrentNode^.next<>Nil then currentNode^.next^.last:=CurrentNode; end; Gruß K-H |
Re: Einfach verkettete Listen
Zitat:
Klar ist es möglich, den TempNode zu umgehen. Fragt sich nur, was besser zu verstehen ist. |
Re: Einfach verkettete Listen
Jo das kommt davon wenn man altes Zeug einfach kopiert!
Die Abfrage
Delphi-Quellcode:
hatte ich geschlabbert.
If FirstNode<>nil then
Nach Meinem Verständnis ist der FirstNode der Anker der Liste, und der CurrentNode ist der "Gleiter". Darum will ich nicht noch eine weitere Variable einführen, mit der ich an der Liste arbeite. Gruß K-H |
AW: Einfach verkettete Listen
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. |
AW: Einfach verkettete Listen
Hallo Bjoerk,
mir ist da nichts aufgefallen. Allerdings hätte ich an Deiner Stelle eine doppelt verkettete Liste genommen, das erspart den immer wiederkehrenden Einstieg über Firstnode. Das hier solltest Du einmal überdenken, da meiner Meinung nach FirstNode FirstNode bleibt, bist FirstNode=NIL!
Delphi-Quellcode:
Und die Definition von TData ist irgendwie doppelt gemoppelt.
procedure TListe.DelItem(Index: integer);
var Node: PNode; begin Node := GetNode(Index-1); DeleteNextNode(Node); FirstNode := GetNode(0); LastNode := GetNode(Count-1); end; Gruß K-H |
AW: Einfach verkettete Listen
thanx!
Wie ist das mit dem inherited (Siehe letzten Teil der Frage)? Ist das erforderlich? |
AW: Einfach verkettete Listen
Mit Gewissheit kann ich es Dir nicht beantworten, Zu dem Thema gab es hier schon einmal eine Diskussion, aber es ist eigentlich nicht falsch.
Gruß K-H Edith: War da nicht etwas mit Free und Destroy? Zitat:
|
AW: Einfach verkettete Listen
Indexe sind aber nicht der Sinn von verketteten Listen. Dabei besser zu TList greifen.
|
AW: Einfach verkettete Listen
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:29 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz