Search code examples
cstructadt

Different structs in the same node Linked Lists C


I am having a bit of difficulty with my assignment and was wondering if someone can point me in the right path.

I wish to create a linked list which supports the use of different nodes, as I need different data sets to be used.

At the moment I am using three structs:

struct equipment_data {
    char EquipID[4+1]; /* 4 Max */
    char EquipName[31+1]; /* 31 Max */
    unsigned TotalNumber;
};

struct member_data {
    unsigned MemberID;
    char LastName[31+1]; /* 31 Max */
    char FirstName[31+1]; /* 31 Max */
};

struct loan_data {
    unsigned MemberID;
    char EquipID[4+1]; /* 4 Max */
    unsigned Number;
};

I need to somehow use this within the same node.

struct ets {
    struct node *equipment_data;
    struct node *member_data;
    struct node *loan_data;
    unsigned equip_count;
    unsigned member_count;
    unsigned loan_count;
};

struct node {
    void *data;
    struct node *next;
};

Looks like I need to create an ADT Linked List. Could you please help? Thanks!


Solution

  • I would make structures for the types that you need to support, and then a union with a type indicator in the linked list node:

    typedef struct { int a, b, c;    } Type1;
    typedef struct { char buf[80];   } Type2;
    typedef struct { int a; float b; } Type3;
    
    typedef union {
        Type1 t1,
        Type2 t2,
        Type3 t3;
    } Anytype;
    
    typedef struct node {
        int thistype;   // 1 for type1, 2 for type2 etc.
        Anytype data;
        struct node *next;
    } Listnode;
    

    Just make sure that you set the thistype right in each Listnode.

    Listnode *node = malloc(sizeof(Listnode));
    node->thistype = 1;  // example: Type1, the 3 ints
    node->t1.a = 1;
    node->t1.b = 2;
    node->t1.c = 3;
    node->next = someothernode;
    

    The you can use a switch to access the data:

    Listnode *node;
    switch (node->thistype) {
        case 1: 
            // do stuff with node->t1.a, node->t1.b, node->t1.c
            break
        case 2:
            // do stuff with node->t2.buf
            break;
        case 3:
            // do stuff with node->t3.a, node.t3.b
            break
    }