Page 1 of 1

beginner class linked list in delphi

PostPosted: March 7th, 2005, 1:45 pm
by x_sanctus
is there any linked list in delphi? or i have to create in myself?

PostPosted: March 7th, 2005, 2:35 pm
by Stefan
Hi,

See this site for a Double Linked list implementation.

See this site for a LIFO stack using a linked list...

Good luck,
Stefan

PostPosted: March 8th, 2005, 11:47 am
by x_sanctus
Stefan wrote:Hi,

See this site for a Double Linked list implementation.

See this site for a LIFO stack using a linked list...

Good luck,
Stefan

hi
i still got a problem i make linked list just like this:

unit ulist;

interface
uses
Windows;
type
PSimpulNode =^TSimpulNode;
Simpul = record
ns :integer;
P : TPoint;
end;

TSimpulNode =record
Next : PSimpulNode;
Info : Simpul;
end;

var
FirstSimpul : PSimpulNode;


procedure AllocNodeSimpul(item :PSimpulNode; ns:integer; P:TPoint);
procedure insertLastSimpul(no : integer; P:TPoint);


implementation

procedure AllocNodeSimpul(item :PSimpulNode;ns:integer;P:TPoint);
begin
New(Item);
Item^.Info.ns:=ns;
Item^.Info.P:=P;
Item^.Next:=nil;
end;

procedure insertLastSimpul(no : integer; P:TPoint);

var
TempNode: PSimpulNode;
newSimpul : PSimpulNode;
begin
AllocNodeSimpul(newSimpul,no,P);
TempNode := FirstSimpul;
while TempNode^.Next <> nil do
begin
TempNode := TempNode^.Next;
end;
TempNode^.Next:=newSimpul;
end;
end.

the procedure insertLastSimpul just dont work. when i call it
error i got messagge access violation at address 000000000. Since i don't familiar with delphi syntax. is there anything wrong in my program? please help...

PostPosted: March 8th, 2005, 12:49 pm
by Stefan
Hi,

please try the following...

Replace insertLastSimpul with:

Code: Select all
procedure insertLastSimpul(no : integer; P:TPoint);
var
  TempNode: PSimpulNode;
  newSimpul : PSimpulNode;
begin
  GetMem(newSimpul, SizeOf(TSimpulNode));
  AllocNodeSimpul(newSimpul,no,P);
  TempNode := @FirstSimpul;
  while TempNode^.Next <> nil do
    TempNode := TempNode^.Next;
  TempNode^.Next:=newSimpul;
end;


if you don't, Delphi gives a warning "Variable newSimpul might not have been initialized"

I've also replaced the global var FirstSimpul:

Code: Select all
var
  FirstSimpul : TSimpulNode;


Hope this helps

Stefan

PostPosted: March 9th, 2005, 11:17 am
by x_sanctus
Stefan wrote:Hi,

please try the following...

Replace insertLastSimpul with:

Code: Select all
procedure insertLastSimpul(no : integer; P:TPoint);
var
  TempNode: PSimpulNode;
  newSimpul : PSimpulNode;
begin
  GetMem(newSimpul, SizeOf(TSimpulNode));
  AllocNodeSimpul(newSimpul,no,P);
  TempNode := @FirstSimpul;
  while TempNode^.Next <> nil do
    TempNode := TempNode^.Next;
  TempNode^.Next:=newSimpul;
end;


if you don't, Delphi gives a warning "Variable newSimpul might not have been initialized"

I've also replaced the global var FirstSimpul:

Code: Select all
var
  FirstSimpul : TSimpulNode;


Hope this helps

Stefan


that was really great help. thanks
but i still get stuck here
hope you don't mind
i have diffrent list
Code: Select all
unit ulist;
interface
uses   Windows;
type
   PSisiNode=^TSisiNode;
   Sisi   = record
      aw   : integer;
      ak   : integer;
      s   : integer;
      v   : integer;
      d   : real;
   end;
   
   TSisiNode   =record
      Next   : PSisiNode;
      Info   : Sisi;
   end;

var   FirstSisi   : TSisiNode;

procedure AllocNodeSisi(item :PSisiNode;aw:integer;ak:integer;
                                        s:integer; v:integer);
function  getDelay(s: integer; v: integer): real;
procedure insertSisi(aw: integer; ak:integer; s:integer ; v: integer);
procedure DeleteAllSisiSimpul(no:integer);

implementation



but i still got problem in insertSisi() and DeleteAll sisi() procedure. when i call it my program hang and still don't understand why can i happened.

Please help.....
Code: Select all
procedure AllocNodeSisi(item :PSisiNode;aw:integer;ak:integer;
                        s:integer; v:integer);
begin
  New(item);
  item^.Next:=nil;
  item^.Info.aw:=aw;
  item^.Info.ak:=ak;
  item^.Info.s:=s;
  item^.Info.v:=v;
  item^.Info.d:=getDelay(s,v);
end;

function getDelay(s: integer; v: integer): real;
begin
   getDelay:=s/v;
end;


Code: Select all
procedure insertSisi(aw: integer; ak:integer; s:integer ; v: integer);
var
   Temp:PSisiNode;
   found:boolean;
   newSisiNode : PSisiNode;
begin
  GetMem(newSisiNode, SizeOf(TSisiNode));
  AllocNodeSisi(newSisiNode,aw,ak,s,v);
    Temp:=@FirstSisi;
   found:=false;
  if(FirstSisi.Info.aw<>0) then
  begin
     while((not found) or (aw <= Temp^.Info.aw) or (Temp<>nil) ) do
     begin
        if((aw=Temp^.Info.aw) and (ak > Temp^.Info.ak)) then
        found:=true
        else
        Temp:=Temp^.Next;
     end;
     if (found) then  //insert after
       begin
          newSisiNode^.Next:=Temp^.Next;
        Temp^.Next:=newSisiNode;
       end
     else   //insert last
        Temp^.Next:=newSisiNode;
  end
  else  //insert first
    begin
         newSisiNode^.next:=@FirstSisi;
   FirstSisi:=newSisiNode^;
    end;
end;

procedure DeleteAllSisiSimpul(no:integer);
//delete all sisi which aw=no
var
  temp:PSisiNode;
  prev:PSisiNode;
  pdel:PSisiNode;
begin
   temp:=@FirstSisi;
  //traversal list
  if(temp^.Next<>nil) then
  begin
     while(((temp^.next).Info.aw <> no) and (temp<>nil )) do
        temp:=temp^.Next;
 
    prev:=temp;
    //deleting
  while((temp.Info.aw=no )or(temp.Next<>nil)) do
    begin
      pdel:=temp;
      Dispose(pdel);
      temp:=temp^.Next;
    end;
     prev^.Next:=temp;
  end
  else
  begin
    if(FirstSisi.Info.aw=no) then
    begin
    Dispose(@FirstSisi);
    end;
  end;
end;
end.


PostPosted: March 9th, 2005, 1:02 pm
by Stefan
There's a couple of problems in the code:

getDelay could return with an invalid floatingpoint operation...
Code: Select all
function getDelay(s: integer; v: integer): real;
begin
  if (s > 0) and (v > 0) then
    getDelay:=s/v
  else
    getDelay:=0;
end;


Instead of using GetMem use New instead (sorry :)):

Code: Select all
procedure insertSisi(aw: integer; ak:integer; s:integer ; v: integer);
...
begin
  New(newSisiNode);
  AllocNodeSisi(newSisiNode,aw,ak,s,v);
...


And leave the New() call out of AllocNodeSisi().

I'd change the FirstSisi back to PSisiNode instead of TSisiNode. That will make it initialize to nil and you can check for that in the insertSisi() procedure:

Code: Select all
  if Assigned(FirstSisi) then begin
    if(FirstSisi^.Info.aw<>0) then begin
    ....   
  else
    FirstSisi := newSisiNode;


That way you will not get an access violation when you try to address it here:

Code: Select all
    if(FirstSisi^.Info.aw<>0) then begin



In the following part you might get stuck in an endless loop:

Code: Select all
while ((not found) or (aw <= Temp^.Info.aw) or (Temp<>nil) ) do begin
  if((aw=Temp^.Info.aw) and (ak > Temp^.Info.ak)) then
    found:=true
  else
    Temp:=Temp^.Next;
endd;


if it's called like this:

Code: Select all
  InsertSisi(1, 1, 1, 1);
  InsertSisi(1, 2, 3, 4);


FirstSisi's aw=1 and ak=1
SecondNode's aw=1 and ak=2 putting you in an endless loop. Remember:

if((aw=Temp^.Info.aw) and (ak > Temp^.Info.ak)) then
found := true;

This will make found = true but this:

while ((not found) or (aw <= Temp^.Info.aw) or (Temp<>nil) ) do begin

will just not care because Temp<>nil (it's got the pointer to FirstSisi) and aw <= Temp^.Info.aw is also true because aw of the second node =1 and FirstSisi's aw=1...

Maybe use a Break in the while loop:

Code: Select all
while ((not found) or (aw <= Temp^.Info.aw) or (Temp<>nil) ) do begin
  if((aw=Temp^.Info.aw) and (ak > Temp^.Info.ak)) then begin
    found:=true;
    break;
  end else
    Temp:=Temp^.Next;
end;


Please work this out first :)

Stefan