Subject: Re: Adding items in a link list... HELP! Date: 31 Jul 1998 02:21:53 EDT From: "Keith" Organization: Concentric Internet Services Newsgroups: comp.lang.pascal.borland Unit LList; { LLIST v1.1 } { (c) 1994 Keith Tysinger -- Released into the Public Domain } { This unit creates a double-linked list that handles Strings } Interface TYPE Plist_rec = ^ List_rec; List_Rec = Record Next_link, Prev_link : Plist_rec; Field : ^String; end; {record} TYPE ListO = Object Private LL,First, Temp,last, Nxt, Prv : Plist_rec; No_Links : word; Public {* INDEXES START AT 1 *} Constructor Init; Procedure Add_Link ( S : String ); { Add new string to LL } Procedure Remove_Link ( LI : word ); { Removes link } Function Current_Link : String; { Returns current link } Procedure Replace_Link ( LI : word; S : String ); Procedure Insert_Link ( LI : word; S : String ); Function Get_Link ( LI : word ): String; { Returns link } Function Goto_Link ( LI : word ) : boolean; { true if sucessful } Function Next_Link : Boolean; { true if sucessful } Function Previous_Link : Boolean; { true if sucessful } Function Number_of_Links : word; Procedure ABC; { Quicksort } Procedure Out_of_Memory_Message; Virtual; Destructor Done; end; {object} Implementation Uses Crt; Constructor ListO.Init; Begin No_Links := 0; First := nil; Last := nil; end; Procedure ListO.Add_Link ( S : String ); Begin if MaxAvail < length(s)+10 then Out_of_Memory_Message; If First = nil then Begin New ( ll ); First := ll; LL^.Prev_Link := nil; LL^.Next_Link := nil; end else Begin ll := Last; New ( ll^.Next_link ); Last := ll; ll := ll^.Next_link; {advance} LL^.Prev_Link := Last; LL^.Next_Link := nil; end; { CREATE ONLY ENOUGH ROOM FOR STRING LENGTH+1: } Getmem ( ll^.Field, Succ ( Length ( S ) ) ); ll^.Field^ := S; Inc ( No_links ); Last := ll; end;{add} Procedure ListO.Replace_Link ( LI : word; S : String ); Begin If not (( LI > no_links ) OR ( LI < 1 ) or (first = nil)) then Begin Goto_Link ( LI ); Freemem ( ll^.field, Succ ( Length ( ll^.field^ ) ) ); Getmem ( ll^.Field, Succ ( Length ( S ) ) ); ll^.Field^ := S; end; end; Procedure ListO.Insert_Link ( LI : word; S : String ) ; Begin If not (( LI > no_links ) OR ( LI < 1 ) or (first = nil)) then Begin Goto_Link ( LI ); If Li = 1 then Begin {FIRST LINK} New ( LL ); ll^.next_link := first; ll^.prev_link := nil; First := ll; ll := ll^.next_link; ll^.prev_link := first; ll := first; end else if Li = no_links then {more than one link & last link} Begin prv := ll^.prev_link; New ( ll ); temp := ll; ll^.next_link := last; ll^.prev_link := prv; ll := Prv; ll^.next_link := temp; ll := last; ll^.prev_link := temp; ll := temp end else Begin {middle link} prv := ll^.prev_link; nxt := ll; New ( ll ); temp := ll; ll^.next_link := nxt; ll^.prev_link := prv; ll := prv; ll^.next_link := temp; ll := nxt; ll^.prev_link := temp; ll := temp; end; Getmem ( ll^.Field, Succ ( Length ( S ) ) ); ll^.Field^ := S; Inc ( No_links ); End else If ( first = nil ) or (li > no_links) then Add_Link ( S ); end; Procedure ListO.Remove_Link ( LI : word ); Begin If not (( LI > no_links ) OR ( LI < 1 ) or (first = nil)) then Begin Goto_link ( li ); If li=1 then {first link} Begin Temp := ll^.next_link; Freemem ( ll^.field, Succ ( Length ( ll^.field^ ) ) ); Dispose ( ll ); If no_links > 1 then Begin First := Temp; ll := first; ll^.prev_link := nil;end else Begin first := nil; last := nil; end; end else if Li = no_links then {nore than one link & last link} Begin Last := ll^.prev_link; Freemem ( ll^.field, Succ ( Length ( ll^.field^ ) ) ); Dispose ( ll ); ll := last; ll^. next_link := nil; end else Begin {more than one link & middle link} Temp := ll; Nxt := ll^.next_link; Prv := ll^.prev_link; Freemem ( ll^.field, Succ ( Length ( ll^.field^ ) ) ); Dispose ( ll ); LL := nxt; ll ^.prev_link := prv; LL := prv; ll^.next_link := Nxt; end; Dec ( No_Links ); end end; Function ListO.Current_Link : String; Begin If first = nil then Current_Link := '' else Current_Link := ll^.field^; end; Function ListO.Get_Link ( LI : word ): String; var L : word; Begin If ( LI > no_links ) OR ( LI < 1 ) or (first = nil) then Get_Link :='' else Begin If li < no_links shr 1 then Begin ll := first; For L := 1 to Pred (LI) do ll := ll^.next_link; end else Begin ll := last; For L := LI to pred (no_links) do ll := ll^.prev_link;; end; Get_Link := ll^.field^; end;{begin} end;{method} Function ListO.Goto_Link ( LI : word ) : boolean; var L : word; Begin If ( LI > (no_links) ) OR ( LI < 0 ) or (first = nil) then Goto_Link :=false else Begin If li < no_links shr 1 then Begin ll := first; For L := 1 to Pred (LI) do ll := ll^.next_link; end else Begin ll := last; For L := LI to pred (no_links) do ll := ll^.prev_link;; end; Goto_Link := true; end;{begin} end;{method} Function ListO.Next_Link : Boolean; Begin If ll^.next_link <> nil then Begin ll := ll^.next_link; next_link := true; end else next_link := false; end; Function ListO.Previous_Link : Boolean; Begin If ll^.prev_link <> nil then Begin ll := ll^.prev_link; Previous_link := true; end else Previous_link := false; end; Function ListO.Number_of_Links : word; Begin Number_of_links := no_links; end; Procedure ListO.ABC; procedure Sort(l, r: Integer); var i, j : Integer; x : String; ip,ij : Pointer; ii,jj : Pointer; C : word; begin i := l; j := r; Goto_link ( (l+r) shr 1 ); x := ll^.field^; repeat { FIND LINK } If i < no_links shr 1 then Begin ll := first; For c := 1 to Pred (I) do ll := ll^.next_link; end else Begin ll := last; For c := I to pred (no_links) do ll := ll^.prev_link;; end; while ll^.field^ < x do Begin Inc (i); LL := ll^.next_link; end; ii := ll; { FIND LINK } If J < no_links shr 1 then Begin ll := first; For c := 1 to Pred (j) do ll := ll^.next_link; end else Begin ll := last; For c := j to pred (no_links) do ll := ll^.prev_link;; end; while x < ll^.field^ do Begin Dec (j); LL := ll^.prev_link; end; jj := ll; if i <= j then begin { Switch string pointer field } ll := ii; ip := ll^.field; ll := jj; ij := ll^.field; ll^.field := ip; ll := ii; ll^.field := ij; Inc (i); Dec (j); end; until i > j; if l < j then Sort(l, j); if i < r then Sort(i, r); end; begin {sort} sort ( 1, no_links ); end; {abc} Destructor ListO.Done; Begin LL := First; While ll <> nil do Begin Last := ll^.next_link; Freemem ( ll^.field, Succ ( Length ( ll^.field^ ) ) ); Dispose ( ll ); ll := last; end; end; Procedure ListO.Out_of_Memory_Message; begin textbackground ( 0 ); textcolor ( 7 ); window ( 1,1,80,25 ); clrscr; Writeln; Writeln ( 'OUT OF MEMORY -- Application terminated.'); sound (8); delay ( 10 ); sound (100); delay ( 10 ); sound (8); delay ( 10 ); nosound; halt; end; end. Hope this helps. This code has been fully tested, but isn't at all guaranteed... Ollie B. Bommel wrote in message <6ppqkv$dn6@reader3.wxs.nl>... >>Could anybody please demonstrate to me how to add items to a link list >>properly. >> >>I guess I don't understand pointers correctly yet. >> >>Any help would be greatly appreciated. >> >>Thanks in advance.. > > >Hi, for a good example on this, take a look at the site www.technojock.com, >they have a very good toolkit of TP including sources. Included are single >and double linked lists. > >Hope this help you, > > >Remko Weijnen