views:

152

answers:

4

I am trying to create a linked list, with two seperate lists in one structure. That is, it holds a 'name' and a 'age' value. Then the program can either output the list sorted by name, or sorted by age. So i need two linked lists, essentially.

However, i need the program to be aware of the root/head of both the name list and the age list.

I'm not sure how to send this to my function.

I will already have the name and the age I want to add to each list, and then somehow I have to send it the head of each list. Because there is two heads i want to return, i cant use the return function. How can I make my main aware of the changes to the head/root lists?

Hopefully the question is clea, and thanks for the answers!

A: 

You can simply pass a pointer to the pointer to the two heads as a argument and then change the pointer without any problem.

 void list_add(char *name, int age, list_type *list, list_type **name_head, list_type **age_head)
 {
     /* Add the name and age and calculate the two heads. */
     (*name_head) = calculated_head;
     (*age_head) = calculated_head;
 }
Kingdom of Fish
+1  A: 

You may wrap both heads in a single structure.

Mr.Cat
A: 
  1. You can use pointers as Kingdom of Fish suggested. I just wanted to add that your documentation should indicate that these values are "outputs" even though they are parameters.

  2. You can use a tuple data-type. Here is a simple one:

    typedef struct Tuple{void*a,*b;}*Tuple;
    Tuple tuple(void*a,void*b){
      Tuple z=malloc(sizeof(struct Tuple));
      z->a=a,z->b=b;
      return z;
    }
    

    Beware though, that tracking dynamically allocating memory can be difficult, and unless you are using a garbage collector, you need to be very careful.

  3. You can use a less-general data structure. For example, you could thread the indexes through the person-object:

    struct Person;typedef struct Person*Person;
    struct Person{Person*prev_by_name,*next_by_name,*prev_by_age,*next_by_age; ...};
    

    Adding additional indexes (linked lists) becomes trivial, and if you give it some thought, you can make the preprocessor do most of the work for you.

    This method also gives you the ability to ask "who is the next-youngest-person after Dave"

    Finally, by threading the indexes in this way, all updates to a person's indexes will be kept together, which will make it easier to avoid synchronization bugs.

  4. You can use separate functions and simply "remember" to call them both. If this is for homework, and you haven't yet addressed how to return multiple values, then you might want to choose this "solution" simply because it's probably what your teacher is looking for.

geocar
+1  A: 

You can link single list item into two lists and sort them independently:

/* List item is linked into two lists */
struct list
{
    struct list* name_next; /* next in name list */
    struct list* age_next;  /* next in age list */

    char*    name;
    unsigned age;
};

/* Holds both list heads */
struct book
{
    struct list* name_sorted;
    struct list* age_sorted;
};
Nikolai N Fetissov