Link to home
Start Free TrialLog in
Avatar of mags2000
mags2000

asked on

How to sort a linked list like this?

Hi, I need some help for this easy problem..
I defined a struct like this:
struct p_list
{
    int n;
    char *nome;
    char *cognome;
    struct p_list *next;
};

typedef struct p_list ELEMENT;
typedef *ELEMENT LINK;

and I need to have a method for creating a list of elements. Something recursive like this:

LINK crealista()
{
LINK head=NULL;
int a;
char *no;
char *co;
scanf("%d %s %s", &a, &no, &co);

if (a != 0)
    {
    head = malloc(sizeof(ELEMENT));
    head->n=a;
    head->nome=no;
    head->cognome=co;
    head->next=crealista();
    }
return head;
}
Suppose this works (not sure of it!), I need a method to put in order the list from the field cognome (italian for Surname!); if two elements have the same surname i order them from the int field..
Can anybody help???
max
Avatar of sarda_ramesh
sarda_ramesh

The first thing is that there is some problem in the createlista() function as it creating a list with only one node .. u need a loop to add more nodes.

One solution of ur problem can be that whenever u add a new record in the list u add it at a position such that the resultant list is always sorted. If u do this way ur problem is automatically solved.

Second solution , if u dont want to change the create list then u can adopt any of the sorting algorithm and modify it accordingly to suit linked lists.

Please let me know which solution will u go for so that i can help u further.

regards
ramesh
Avatar of mags2000

ASKER

thanks sarda_ramesh, the first solution is not a bad idea.. My future problem will be that i will have lot of these lists, and i need to make one out of them, and then order the whole one...
So I don't know if it is useful to order the partial lists alone. I will work on it for another while, will let you know!
mags2000
Sarda,

Excuse me, but if you look carefully at the function, he is creating a more than one element.  creatlista is being called recursively until a 0 is entered as the first element in the scanf.

Second the link you gave is for C++ code.  This is the C forum...

mags2000,

You do have a bug, though...

You define your structure as

struct p_list
{
   int n;
   char *nome;
   char *cognome;
   struct p_list *next;
};

Please note that both nome and cognome are pointers to strings - they reserve no memory for the strings themselves.

When you use scanf, you also use pointers to strings that have not been allocated - your program WILL crash.

I suggest the following...

Leave your struct definition alone.

In createlista, declare the temporary strings to be large enough to hold any name, say

char no[100];
char co[100];

then change the loop to be as follows:

if (a != 0)
   {
   head = malloc(sizeof(ELEMENT));
   head->n=a;
   head->nome=malloc(strlen(no)+1);
   strcpy(head->nome,no);
   head->cognome=malloc(strlen(co)+1);
   strcpy(head->cognome,co);
   head->next=crealista();
   }

You can't just set head->nome=no, because no is just a temporary variable on the stack - it disappears once the function returns...

If you can't use the C++ versions let us know, it is easy enough to sort a linked list in C.

One note on your code - you are returning the pointer to the last element in your list, fyi..
thank you gj62, in effect the crealista() is recursive and it works well with your suggestion!
I can't use C++, only C is available for sorting this list. I would prefer to use only one pointer to next, avoiding a previos pointer...
mags,

go to here:

http://www.snippets.org/snippets/portable/portable.php3

Download LL_MSORT.C and SNIPSORT.H.

You need to make only a few modifications:

In SNIPSORT.H, replace your struct for the list_struct.

In LL_MSORT, change the compare rountine to:

/* returns < 0 if *p sorts lower than *q */
int keycmp (list *p, list *q)
{
      if (strcmp(p->cogname, q->cogname)==0)
      {
        if (p->a > p->q) return(1);
        return(-1);
      }

      return strcmp(p->cogname, q->cogname);
}

This should do the trick - remember, strcmp is case sensitive - if you need case insensitive, let me know...
ASKER CERTIFIED SOLUTION
Avatar of gj62
gj62

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
you did it! Thanks a lot gj62, I was near a solution like your one, but this is better!
mags