Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site utcsri.UUCP Path: utzoo!utcsri!greg From: greg@utcsri.UUCP (Gregory Smith) Newsgroups: net.lang.c Subject: Re: Sorting linked lists Message-ID: <2349@utcsri.UUCP> Date: Tue, 18-Mar-86 12:12:15 EST Article-I.D.: utcsri.2349 Posted: Tue Mar 18 12:12:15 1986 Date-Received: Tue, 18-Mar-86 12:21:25 EST References: <165@ablnc.UUCP> <337@umcp-cs.UUCP> Reply-To: greg@utcsri.UUCP (Gregory Smith) Organization: CSRI, University of Toronto Lines: 62 Keywords: Sort link-list Summary: In article <337@umcp-cs.UUCP> chris@umcp-cs.UUCP (Chris Torek) writes: >In article <165@ablnc.UUCP> rcpilz@ablnc.UUCP writes: >>I would like to know if there is a way to sort a linked list. >You get to roll your own. I started to think about this, and blew >a couple of hours writing the code below. This will work on a >doubly linked list if you turn it into a tree first. (You can turn [ 300+ lines of code deleted ] You can use qsort. Just malloc up an array of pointers ( assume the linked list is made of struct foo's:) struct foo **Index; /* pointer to the array */ Index = ( struct foo **) malloc( list_size * sizeof( struct foo *)); Then fill in this array with pointers to each element in the linked list. struct foo * Head; /* head of list */ register struct foo *rp, **bp; rp = Head; bp = Index; while( rp ){ *bp++ = rp; rp = rp->link; } Then: qsort( Index, list_size, sizeof( struct foo*), comp ); Note that we are sorting the pointer array, not the actual list. This means that 'comp(a,b)' is handed two pointers to pointers to struct foo: comp(a,b) struct foo **a,**b; { return strcmp( (*a)->name, (*b)->name)); } ( The above will sort on a 'name' element within foo which is of type char * or char [] ) After that, you have an array of pointers to the list which is ordered the way you want it. You can use this to traverse the list, or you can use it to re-link the list in the correct order: for(i=0; ilink = Index[i+1]; /* indexing used instead of pointers for clarity*/ } Index[ list_size-1] = 0; /* end of list */ Head = Index[0]; /* new list head */ free( Index ); /* done! */ Of course, the actual foo records themselves have not moved. This is _the_ way to go if the list is long and the records are too large to copy. The heap sort given by Chris Torek may be slightly faster, but I don't like writing or debugging big sort routines so I like to use qsort whenever possible. -- "No eternal reward will forgive us now for wasting the dawn" -J. Morrison ---------------------------------------------------------------------- Greg Smith University of Toronto ..!decvax!utzoo!utcsri!greg