5

I am making a project and was wondering if I could create a linked list of linked lists. I want to create a new type person in C in which, every person can have kids. kids are a list of persons and also every person has parents who are also persons.So I am thinking of doing that using structs and linked lists.

#include <stdio.h>

struct person {
unsigned int id;    //identity,unique for every person
char* name;
struct person **father;
struct person **mother;
struct kids **kids;
}

struct kids {
struct person **kid;
struct kids **next_kid;
}; 

Thank you in advance for your time.

4
  • 9
    Yes, you can. Do you have another question ? Commented Jan 4, 2015 at 17:36
  • 1
    I'm not sure why you've declared pointer to pointer (person **father) all over. person *father will probably do. Oh and as @Quentin says "Sure can buddy". And the rest and so on ad infinitum. Welcome to the wonderful world of complex data structures. Commented Jan 4, 2015 at 17:44
  • Just use single pointers in the structures. For the function code, you may want to use pointers to pointers to structures so that you don't need special handling for the head pointer versus the next pointers. For example, to initialize: node **ppnode = &head; to advance: ppnode = &((*ppnode)->next); . Commented Jan 4, 2015 at 18:39
  • Thank you very much for your responses.I wasn't quite sure.@DanAllen The reason why i did double pointers is so when i change or initialize someones parent i will not have to return something all my functions will be void instead of type person( void define_father(person p,person father); instead of 'p->father=define_father(person p,person father);' ) Commented Jan 4, 2015 at 18:46

1 Answer 1

9

Yes, you can have lists of lists, one example of which is shown below, a list of children each with their own list of toys.

First, the relevant header files and structures for the two types of objects (children and toys):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct sToy {
    char name[50];
    struct sToy *next;
} tToy;

typedef struct sChild {
    char name[50];
    tToy *firstToy;
    struct sChild *next;
} tChild;

Then, a helper function for allocating memory so I don't have to pollute the sample with lots of error checking:

void *chkMalloc (size_t sz) {
    void *mem = malloc (sz);

    // Just fail immediately on error.

    if (mem == NULL) {
        printf ("Out of memory! Exiting.\n");
        exit (1);
    }

    // Otherwise we know it worked.

    return mem;
}

Next, helper functions to allocate the two types of object and insert them into the relevant list. Note that I'm inserting at the start of the list to simplify the code, so we don't have to worry about list traversal or storing the final item pointer as well.

That means everything will be printed in reverse order when dumping the details but that's a small price to pay for keeping things simple:

void addChild (tChild **first, char *name) {
    // Insert new item at start.

    tChild *newest = chkMalloc (sizeof (*newest));
    strcpy (newest->name, name);
    newest->next = *first;
    *first = newest;
}

void addToy (tChild *first, char *name) {
    // Insert at start of list.

    tToy *newest = chkMalloc (sizeof (*newest));
    strcpy (newest->name, name);
    newest->next = first->firstToy;
    first->firstToy = newest;
}

Next, the function for dumping the lists in readable format:

void dumpDetails (tChild *currChild) {
    // For every child.

    while (currChild != NULL) {
        printf ("%s has:\n", currChild->name);

        // For every toy that child has.

        tToy *currToy = currChild->firstToy;
        if (currToy == NULL) {
            printf ("   <<nothing>>\n");
        } else {
            while (currToy != NULL) {
                printf ("   %s\n", currToy->name);
                currToy = currToy->next;
            }
        }
        currChild = currChild->next;
    }
}

And, lastly, a main function for tying all the others together:

int main (void) {
    tChild *firstChild = NULL;

    addChild (&firstChild, "Anita");
        addToy (firstChild, "skipping rope");
    addChild (&firstChild, "Beth");
    addChild (&firstChild, "Carla");
        addToy (firstChild, "model car");
        addToy (firstChild, "trampoline");

    dumpDetails (firstChild);

    return 0;
}

When you enter, compile and run all that code, you can see that it quite easily handles lists of lists:

Carla has:
   trampoline
   model car
Beth has:
   <<nothing>>
Anita has:
   skipping rope
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you so much for you time and effort now everything seems less confusing.
How would you add an owner to a toy? That would mean you would have to add a pointer to struct sChild into struct sToy, but struct sChild is not known yet.
@nobody, you are allowed to have pointers to incomplete structures so you can put a struct sChild; declaration before the sToy definition, which can then have something like struct sChild *owner; added.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.