size : 3863 uploaded_on : Wed Oct 14 00:00:00 1998 modified_on : Wed Dec 8 14:03:17 1999 title : Sort linked list org_filename : SortLinkedList.txt author : Peter Below authoremail : description : An example on sorting linked lists keywords : tested : not tested yet submitted_by : Mike Orriss submitted_by_email : mjo@3kcc.co.uk uploaded_by : nobody modified_by : nobody owner : nobody lang : plain file-type : text/plain category : delphi-misc __END_OF_HEADER__ Here is a sample: program noname; Type PData = ^TData; TData = Record next: PData; Name: String[ 40 ]; { ...other data fields } End; Var root: PData; { this is the pointer to the first record in the linked list } Procedure InsertRecord( Var root: PData; pItem: PData ); (* insert the record pointed to by pItem into the list starting at root at the proper place required by sort order *) Var pWalk, pLast: PData; Begin If root = Nil Then Begin (* new list is still empty, just make the record to add the root of the new list *) root := pItem; root^.next := Nil End { If } Else Begin (* walk thru the list and compare each record with the one to insert. We need to remember the last record we checked, for reasons that will become appearend later. *) pWalk := root; pLast := Nil; (* the condition in the following While statement determines the sort order! This would be an ideal place to put in a call to a comparison function you pass as additional parameter to InsertRecord, to make it a generic sort, e.g. While CompareItems( pWalk, pItem ) < 0 Do Begin where Procedure InsertRecord( Var list: PData; CompareItems: TCompareItems ); and Type TCompareItems = Function( p1,p2:PData ): Integer; and a sample compare function: Function CompareName( p1,p2:PData ): Integer; Begin If p1^.Name < p2^.Name Then CompareName := -1 Else If p1^.Name > p2^.Name Then CompareName := 1 Else CompareName := 0; End; *) While pWalk^.Name < pItem^.Name Do If pWalk^.next = Nil Then Begin (* we found the end of the list, so append the new record there and exit this procedure *) pWalk^.next := pItem; pItem^.next := Nil; Exit; End { If } Else Begin (* next record, please, but remember the one we just checked! *) pLast := pWalk; (* if we end up here we found a record in the list that is >= the one to insert. So insert it before the record pWalk currently points at, which is after pLast. *) If pLast = Nil Then Begin (* Oops, we fell out of the while loop on the very first round! The new record has to go to the top of the list, so it becomes the new root! *) pItem^.next := root; root := pItem; End { If } Else Begin (* insert pItem between pLast and pWalk *) pItem^.next := pWalk; pLast^.next := pItem; End; { Else } (* and we are done! *) End; { Else } End; { InsertRecord } Procedure SortbyName( Var list: PData ); Var newtree, temp, stump: PData; Begin { SortByName } (* exit immediately if there is nothing to sort *) If list = Nil then Exit; (* in newtree := Nil; (******** We sort simply by taking records off the original list and insert them into a new one we hook to newtree at the right position. Stump is used to hold the remainder of the list. temp is used to point at the record we move from one list to the other. ********) stump := list; While stump <> Nil Do Begin (* point temp at the record to move *) temp := stump; (* disconnect it from the list *) stump := stump^.next; (* insert it into the new list *) InsertRecord( newtree, temp ); End; { While } (* now put the start of the new, sorted tree into the old list start *) list := newtree; End; { SortByName } Begin New(root); root^.Name := 'BETA'; New(root^.next); root^.next^.Name := 'ALPHA'; New(root^.next^.next); root^.next^.next^.Name := 'Torture'; WriteLn( root^.name ); WriteLn( root^.next^.name ); WriteLn( root^.next^.next^.name ); End. - Peter Below