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
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
http://www.csc.ncsu.edu/eos/users/e/efg/210/s99/course_locker/www/Notes/Sorting/Code/
for help on sorting linked lists
for help on sorting linked lists
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
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(n o)+1);
strcpy(head->nome,no);
head->cognome=malloc(strle n(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..
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(n
strcpy(head->nome,no);
head->cognome=malloc(strle
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..
ASKER
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...
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...
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
you did it! Thanks a lot gj62, I was near a solution like your one, but this is better!
mags
mags
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